file.c 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * SPU file system -- file contents
  4. *
  5. * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
  6. *
  7. * Author: Arnd Bergmann <arndb@de.ibm.com>
  8. */
  9. #undef DEBUG
  10. #include <linux/coredump.h>
  11. #include <linux/fs.h>
  12. #include <linux/ioctl.h>
  13. #include <linux/export.h>
  14. #include <linux/pagemap.h>
  15. #include <linux/poll.h>
  16. #include <linux/ptrace.h>
  17. #include <linux/seq_file.h>
  18. #include <linux/slab.h>
  19. #include <asm/io.h>
  20. #include <asm/time.h>
  21. #include <asm/spu.h>
  22. #include <asm/spu_info.h>
  23. #include <linux/uaccess.h>
  24. #include "spufs.h"
  25. #include "sputrace.h"
  26. #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
  27. /* Simple attribute files */
  28. struct spufs_attr {
  29. int (*get)(void *, u64 *);
  30. int (*set)(void *, u64);
  31. char get_buf[24]; /* enough to store a u64 and "\n\0" */
  32. char set_buf[24];
  33. void *data;
  34. const char *fmt; /* format for read operation */
  35. struct mutex mutex; /* protects access to these buffers */
  36. };
  37. static int spufs_attr_open(struct inode *inode, struct file *file,
  38. int (*get)(void *, u64 *), int (*set)(void *, u64),
  39. const char *fmt)
  40. {
  41. struct spufs_attr *attr;
  42. attr = kmalloc(sizeof(*attr), GFP_KERNEL);
  43. if (!attr)
  44. return -ENOMEM;
  45. attr->get = get;
  46. attr->set = set;
  47. attr->data = inode->i_private;
  48. attr->fmt = fmt;
  49. mutex_init(&attr->mutex);
  50. file->private_data = attr;
  51. return nonseekable_open(inode, file);
  52. }
  53. static int spufs_attr_release(struct inode *inode, struct file *file)
  54. {
  55. kfree(file->private_data);
  56. return 0;
  57. }
  58. static ssize_t spufs_attr_read(struct file *file, char __user *buf,
  59. size_t len, loff_t *ppos)
  60. {
  61. struct spufs_attr *attr;
  62. size_t size;
  63. ssize_t ret;
  64. attr = file->private_data;
  65. if (!attr->get)
  66. return -EACCES;
  67. ret = mutex_lock_interruptible(&attr->mutex);
  68. if (ret)
  69. return ret;
  70. if (*ppos) { /* continued read */
  71. size = strlen(attr->get_buf);
  72. } else { /* first read */
  73. u64 val;
  74. ret = attr->get(attr->data, &val);
  75. if (ret)
  76. goto out;
  77. size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
  78. attr->fmt, (unsigned long long)val);
  79. }
  80. ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
  81. out:
  82. mutex_unlock(&attr->mutex);
  83. return ret;
  84. }
  85. static ssize_t spufs_attr_write(struct file *file, const char __user *buf,
  86. size_t len, loff_t *ppos)
  87. {
  88. struct spufs_attr *attr;
  89. u64 val;
  90. size_t size;
  91. ssize_t ret;
  92. attr = file->private_data;
  93. if (!attr->set)
  94. return -EACCES;
  95. ret = mutex_lock_interruptible(&attr->mutex);
  96. if (ret)
  97. return ret;
  98. ret = -EFAULT;
  99. size = min(sizeof(attr->set_buf) - 1, len);
  100. if (copy_from_user(attr->set_buf, buf, size))
  101. goto out;
  102. ret = len; /* claim we got the whole input */
  103. attr->set_buf[size] = '\0';
  104. val = simple_strtol(attr->set_buf, NULL, 0);
  105. attr->set(attr->data, val);
  106. out:
  107. mutex_unlock(&attr->mutex);
  108. return ret;
  109. }
  110. static ssize_t spufs_dump_emit(struct coredump_params *cprm, void *buf,
  111. size_t size)
  112. {
  113. if (!dump_emit(cprm, buf, size))
  114. return -EIO;
  115. return size;
  116. }
  117. #define DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
  118. static int __fops ## _open(struct inode *inode, struct file *file) \
  119. { \
  120. __simple_attr_check_format(__fmt, 0ull); \
  121. return spufs_attr_open(inode, file, __get, __set, __fmt); \
  122. } \
  123. static const struct file_operations __fops = { \
  124. .open = __fops ## _open, \
  125. .release = spufs_attr_release, \
  126. .read = spufs_attr_read, \
  127. .write = spufs_attr_write, \
  128. .llseek = generic_file_llseek, \
  129. };
  130. static int
  131. spufs_mem_open(struct inode *inode, struct file *file)
  132. {
  133. struct spufs_inode_info *i = SPUFS_I(inode);
  134. struct spu_context *ctx = i->i_ctx;
  135. mutex_lock(&ctx->mapping_lock);
  136. file->private_data = ctx;
  137. if (!i->i_openers++)
  138. ctx->local_store = inode->i_mapping;
  139. mutex_unlock(&ctx->mapping_lock);
  140. return 0;
  141. }
  142. static int
  143. spufs_mem_release(struct inode *inode, struct file *file)
  144. {
  145. struct spufs_inode_info *i = SPUFS_I(inode);
  146. struct spu_context *ctx = i->i_ctx;
  147. mutex_lock(&ctx->mapping_lock);
  148. if (!--i->i_openers)
  149. ctx->local_store = NULL;
  150. mutex_unlock(&ctx->mapping_lock);
  151. return 0;
  152. }
  153. static ssize_t
  154. spufs_mem_dump(struct spu_context *ctx, struct coredump_params *cprm)
  155. {
  156. return spufs_dump_emit(cprm, ctx->ops->get_ls(ctx), LS_SIZE);
  157. }
  158. static ssize_t
  159. spufs_mem_read(struct file *file, char __user *buffer,
  160. size_t size, loff_t *pos)
  161. {
  162. struct spu_context *ctx = file->private_data;
  163. ssize_t ret;
  164. ret = spu_acquire(ctx);
  165. if (ret)
  166. return ret;
  167. ret = simple_read_from_buffer(buffer, size, pos, ctx->ops->get_ls(ctx),
  168. LS_SIZE);
  169. spu_release(ctx);
  170. return ret;
  171. }
  172. static ssize_t
  173. spufs_mem_write(struct file *file, const char __user *buffer,
  174. size_t size, loff_t *ppos)
  175. {
  176. struct spu_context *ctx = file->private_data;
  177. char *local_store;
  178. loff_t pos = *ppos;
  179. int ret;
  180. if (pos > LS_SIZE)
  181. return -EFBIG;
  182. ret = spu_acquire(ctx);
  183. if (ret)
  184. return ret;
  185. local_store = ctx->ops->get_ls(ctx);
  186. size = simple_write_to_buffer(local_store, LS_SIZE, ppos, buffer, size);
  187. spu_release(ctx);
  188. return size;
  189. }
  190. static vm_fault_t
  191. spufs_mem_mmap_fault(struct vm_fault *vmf)
  192. {
  193. struct vm_area_struct *vma = vmf->vma;
  194. struct spu_context *ctx = vma->vm_file->private_data;
  195. unsigned long pfn, offset;
  196. vm_fault_t ret;
  197. offset = vmf->pgoff << PAGE_SHIFT;
  198. if (offset >= LS_SIZE)
  199. return VM_FAULT_SIGBUS;
  200. pr_debug("spufs_mem_mmap_fault address=0x%lx, offset=0x%lx\n",
  201. vmf->address, offset);
  202. if (spu_acquire(ctx))
  203. return VM_FAULT_NOPAGE;
  204. if (ctx->state == SPU_STATE_SAVED) {
  205. vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
  206. pfn = vmalloc_to_pfn(ctx->csa.lscsa->ls + offset);
  207. } else {
  208. vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot);
  209. pfn = (ctx->spu->local_store_phys + offset) >> PAGE_SHIFT;
  210. }
  211. ret = vmf_insert_pfn(vma, vmf->address, pfn);
  212. spu_release(ctx);
  213. return ret;
  214. }
  215. static int spufs_mem_mmap_access(struct vm_area_struct *vma,
  216. unsigned long address,
  217. void *buf, int len, int write)
  218. {
  219. struct spu_context *ctx = vma->vm_file->private_data;
  220. unsigned long offset = address - vma->vm_start;
  221. char *local_store;
  222. if (write && !(vma->vm_flags & VM_WRITE))
  223. return -EACCES;
  224. if (spu_acquire(ctx))
  225. return -EINTR;
  226. if ((offset + len) > vma->vm_end)
  227. len = vma->vm_end - offset;
  228. local_store = ctx->ops->get_ls(ctx);
  229. if (write)
  230. memcpy_toio(local_store + offset, buf, len);
  231. else
  232. memcpy_fromio(buf, local_store + offset, len);
  233. spu_release(ctx);
  234. return len;
  235. }
  236. static const struct vm_operations_struct spufs_mem_mmap_vmops = {
  237. .fault = spufs_mem_mmap_fault,
  238. .access = spufs_mem_mmap_access,
  239. };
  240. static int spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
  241. {
  242. if (!(vma->vm_flags & VM_SHARED))
  243. return -EINVAL;
  244. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  245. vma->vm_page_prot = pgprot_noncached_wc(vma->vm_page_prot);
  246. vma->vm_ops = &spufs_mem_mmap_vmops;
  247. return 0;
  248. }
  249. static const struct file_operations spufs_mem_fops = {
  250. .open = spufs_mem_open,
  251. .release = spufs_mem_release,
  252. .read = spufs_mem_read,
  253. .write = spufs_mem_write,
  254. .llseek = generic_file_llseek,
  255. .mmap = spufs_mem_mmap,
  256. };
  257. static vm_fault_t spufs_ps_fault(struct vm_fault *vmf,
  258. unsigned long ps_offs,
  259. unsigned long ps_size)
  260. {
  261. struct spu_context *ctx = vmf->vma->vm_file->private_data;
  262. unsigned long area, offset = vmf->pgoff << PAGE_SHIFT;
  263. int err = 0;
  264. vm_fault_t ret = VM_FAULT_NOPAGE;
  265. spu_context_nospu_trace(spufs_ps_fault__enter, ctx);
  266. if (offset >= ps_size)
  267. return VM_FAULT_SIGBUS;
  268. if (fatal_signal_pending(current))
  269. return VM_FAULT_SIGBUS;
  270. /*
  271. * Because we release the mmap_lock, the context may be destroyed while
  272. * we're in spu_wait. Grab an extra reference so it isn't destroyed
  273. * in the meantime.
  274. */
  275. get_spu_context(ctx);
  276. /*
  277. * We have to wait for context to be loaded before we have
  278. * pages to hand out to the user, but we don't want to wait
  279. * with the mmap_lock held.
  280. * It is possible to drop the mmap_lock here, but then we need
  281. * to return VM_FAULT_NOPAGE because the mappings may have
  282. * hanged.
  283. */
  284. if (spu_acquire(ctx))
  285. goto refault;
  286. if (ctx->state == SPU_STATE_SAVED) {
  287. mmap_read_unlock(current->mm);
  288. spu_context_nospu_trace(spufs_ps_fault__sleep, ctx);
  289. err = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
  290. spu_context_trace(spufs_ps_fault__wake, ctx, ctx->spu);
  291. mmap_read_lock(current->mm);
  292. } else {
  293. area = ctx->spu->problem_phys + ps_offs;
  294. ret = vmf_insert_pfn(vmf->vma, vmf->address,
  295. (area + offset) >> PAGE_SHIFT);
  296. spu_context_trace(spufs_ps_fault__insert, ctx, ctx->spu);
  297. }
  298. if (!err)
  299. spu_release(ctx);
  300. refault:
  301. put_spu_context(ctx);
  302. return ret;
  303. }
  304. #if SPUFS_MMAP_4K
  305. static vm_fault_t spufs_cntl_mmap_fault(struct vm_fault *vmf)
  306. {
  307. return spufs_ps_fault(vmf, 0x4000, SPUFS_CNTL_MAP_SIZE);
  308. }
  309. static const struct vm_operations_struct spufs_cntl_mmap_vmops = {
  310. .fault = spufs_cntl_mmap_fault,
  311. };
  312. /*
  313. * mmap support for problem state control area [0x4000 - 0x4fff].
  314. */
  315. static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
  316. {
  317. if (!(vma->vm_flags & VM_SHARED))
  318. return -EINVAL;
  319. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  320. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  321. vma->vm_ops = &spufs_cntl_mmap_vmops;
  322. return 0;
  323. }
  324. #else /* SPUFS_MMAP_4K */
  325. #define spufs_cntl_mmap NULL
  326. #endif /* !SPUFS_MMAP_4K */
  327. static int spufs_cntl_get(void *data, u64 *val)
  328. {
  329. struct spu_context *ctx = data;
  330. int ret;
  331. ret = spu_acquire(ctx);
  332. if (ret)
  333. return ret;
  334. *val = ctx->ops->status_read(ctx);
  335. spu_release(ctx);
  336. return 0;
  337. }
  338. static int spufs_cntl_set(void *data, u64 val)
  339. {
  340. struct spu_context *ctx = data;
  341. int ret;
  342. ret = spu_acquire(ctx);
  343. if (ret)
  344. return ret;
  345. ctx->ops->runcntl_write(ctx, val);
  346. spu_release(ctx);
  347. return 0;
  348. }
  349. static int spufs_cntl_open(struct inode *inode, struct file *file)
  350. {
  351. struct spufs_inode_info *i = SPUFS_I(inode);
  352. struct spu_context *ctx = i->i_ctx;
  353. mutex_lock(&ctx->mapping_lock);
  354. file->private_data = ctx;
  355. if (!i->i_openers++)
  356. ctx->cntl = inode->i_mapping;
  357. mutex_unlock(&ctx->mapping_lock);
  358. return simple_attr_open(inode, file, spufs_cntl_get,
  359. spufs_cntl_set, "0x%08lx");
  360. }
  361. static int
  362. spufs_cntl_release(struct inode *inode, struct file *file)
  363. {
  364. struct spufs_inode_info *i = SPUFS_I(inode);
  365. struct spu_context *ctx = i->i_ctx;
  366. simple_attr_release(inode, file);
  367. mutex_lock(&ctx->mapping_lock);
  368. if (!--i->i_openers)
  369. ctx->cntl = NULL;
  370. mutex_unlock(&ctx->mapping_lock);
  371. return 0;
  372. }
  373. static const struct file_operations spufs_cntl_fops = {
  374. .open = spufs_cntl_open,
  375. .release = spufs_cntl_release,
  376. .read = simple_attr_read,
  377. .write = simple_attr_write,
  378. .mmap = spufs_cntl_mmap,
  379. };
  380. static int
  381. spufs_regs_open(struct inode *inode, struct file *file)
  382. {
  383. struct spufs_inode_info *i = SPUFS_I(inode);
  384. file->private_data = i->i_ctx;
  385. return 0;
  386. }
  387. static ssize_t
  388. spufs_regs_dump(struct spu_context *ctx, struct coredump_params *cprm)
  389. {
  390. return spufs_dump_emit(cprm, ctx->csa.lscsa->gprs,
  391. sizeof(ctx->csa.lscsa->gprs));
  392. }
  393. static ssize_t
  394. spufs_regs_read(struct file *file, char __user *buffer,
  395. size_t size, loff_t *pos)
  396. {
  397. int ret;
  398. struct spu_context *ctx = file->private_data;
  399. /* pre-check for file position: if we'd return EOF, there's no point
  400. * causing a deschedule */
  401. if (*pos >= sizeof(ctx->csa.lscsa->gprs))
  402. return 0;
  403. ret = spu_acquire_saved(ctx);
  404. if (ret)
  405. return ret;
  406. ret = simple_read_from_buffer(buffer, size, pos, ctx->csa.lscsa->gprs,
  407. sizeof(ctx->csa.lscsa->gprs));
  408. spu_release_saved(ctx);
  409. return ret;
  410. }
  411. static ssize_t
  412. spufs_regs_write(struct file *file, const char __user *buffer,
  413. size_t size, loff_t *pos)
  414. {
  415. struct spu_context *ctx = file->private_data;
  416. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  417. int ret;
  418. if (*pos >= sizeof(lscsa->gprs))
  419. return -EFBIG;
  420. ret = spu_acquire_saved(ctx);
  421. if (ret)
  422. return ret;
  423. size = simple_write_to_buffer(lscsa->gprs, sizeof(lscsa->gprs), pos,
  424. buffer, size);
  425. spu_release_saved(ctx);
  426. return size;
  427. }
  428. static const struct file_operations spufs_regs_fops = {
  429. .open = spufs_regs_open,
  430. .read = spufs_regs_read,
  431. .write = spufs_regs_write,
  432. .llseek = generic_file_llseek,
  433. };
  434. static ssize_t
  435. spufs_fpcr_dump(struct spu_context *ctx, struct coredump_params *cprm)
  436. {
  437. return spufs_dump_emit(cprm, &ctx->csa.lscsa->fpcr,
  438. sizeof(ctx->csa.lscsa->fpcr));
  439. }
  440. static ssize_t
  441. spufs_fpcr_read(struct file *file, char __user * buffer,
  442. size_t size, loff_t * pos)
  443. {
  444. int ret;
  445. struct spu_context *ctx = file->private_data;
  446. ret = spu_acquire_saved(ctx);
  447. if (ret)
  448. return ret;
  449. ret = simple_read_from_buffer(buffer, size, pos, &ctx->csa.lscsa->fpcr,
  450. sizeof(ctx->csa.lscsa->fpcr));
  451. spu_release_saved(ctx);
  452. return ret;
  453. }
  454. static ssize_t
  455. spufs_fpcr_write(struct file *file, const char __user * buffer,
  456. size_t size, loff_t * pos)
  457. {
  458. struct spu_context *ctx = file->private_data;
  459. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  460. int ret;
  461. if (*pos >= sizeof(lscsa->fpcr))
  462. return -EFBIG;
  463. ret = spu_acquire_saved(ctx);
  464. if (ret)
  465. return ret;
  466. size = simple_write_to_buffer(&lscsa->fpcr, sizeof(lscsa->fpcr), pos,
  467. buffer, size);
  468. spu_release_saved(ctx);
  469. return size;
  470. }
  471. static const struct file_operations spufs_fpcr_fops = {
  472. .open = spufs_regs_open,
  473. .read = spufs_fpcr_read,
  474. .write = spufs_fpcr_write,
  475. .llseek = generic_file_llseek,
  476. };
  477. /* generic open function for all pipe-like files */
  478. static int spufs_pipe_open(struct inode *inode, struct file *file)
  479. {
  480. struct spufs_inode_info *i = SPUFS_I(inode);
  481. file->private_data = i->i_ctx;
  482. return stream_open(inode, file);
  483. }
  484. /*
  485. * Read as many bytes from the mailbox as possible, until
  486. * one of the conditions becomes true:
  487. *
  488. * - no more data available in the mailbox
  489. * - end of the user provided buffer
  490. * - end of the mapped area
  491. */
  492. static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
  493. size_t len, loff_t *pos)
  494. {
  495. struct spu_context *ctx = file->private_data;
  496. u32 mbox_data, __user *udata = (void __user *)buf;
  497. ssize_t count;
  498. if (len < 4)
  499. return -EINVAL;
  500. count = spu_acquire(ctx);
  501. if (count)
  502. return count;
  503. for (count = 0; (count + 4) <= len; count += 4, udata++) {
  504. int ret;
  505. ret = ctx->ops->mbox_read(ctx, &mbox_data);
  506. if (ret == 0)
  507. break;
  508. /*
  509. * at the end of the mapped area, we can fault
  510. * but still need to return the data we have
  511. * read successfully so far.
  512. */
  513. ret = put_user(mbox_data, udata);
  514. if (ret) {
  515. if (!count)
  516. count = -EFAULT;
  517. break;
  518. }
  519. }
  520. spu_release(ctx);
  521. if (!count)
  522. count = -EAGAIN;
  523. return count;
  524. }
  525. static const struct file_operations spufs_mbox_fops = {
  526. .open = spufs_pipe_open,
  527. .read = spufs_mbox_read,
  528. };
  529. static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
  530. size_t len, loff_t *pos)
  531. {
  532. struct spu_context *ctx = file->private_data;
  533. ssize_t ret;
  534. u32 mbox_stat;
  535. if (len < 4)
  536. return -EINVAL;
  537. ret = spu_acquire(ctx);
  538. if (ret)
  539. return ret;
  540. mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
  541. spu_release(ctx);
  542. if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat))
  543. return -EFAULT;
  544. return 4;
  545. }
  546. static const struct file_operations spufs_mbox_stat_fops = {
  547. .open = spufs_pipe_open,
  548. .read = spufs_mbox_stat_read,
  549. };
  550. /* low-level ibox access function */
  551. size_t spu_ibox_read(struct spu_context *ctx, u32 *data)
  552. {
  553. return ctx->ops->ibox_read(ctx, data);
  554. }
  555. /* interrupt-level ibox callback function. */
  556. void spufs_ibox_callback(struct spu *spu)
  557. {
  558. struct spu_context *ctx = spu->ctx;
  559. if (ctx)
  560. wake_up_all(&ctx->ibox_wq);
  561. }
  562. /*
  563. * Read as many bytes from the interrupt mailbox as possible, until
  564. * one of the conditions becomes true:
  565. *
  566. * - no more data available in the mailbox
  567. * - end of the user provided buffer
  568. * - end of the mapped area
  569. *
  570. * If the file is opened without O_NONBLOCK, we wait here until
  571. * any data is available, but return when we have been able to
  572. * read something.
  573. */
  574. static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
  575. size_t len, loff_t *pos)
  576. {
  577. struct spu_context *ctx = file->private_data;
  578. u32 ibox_data, __user *udata = (void __user *)buf;
  579. ssize_t count;
  580. if (len < 4)
  581. return -EINVAL;
  582. count = spu_acquire(ctx);
  583. if (count)
  584. goto out;
  585. /* wait only for the first element */
  586. count = 0;
  587. if (file->f_flags & O_NONBLOCK) {
  588. if (!spu_ibox_read(ctx, &ibox_data)) {
  589. count = -EAGAIN;
  590. goto out_unlock;
  591. }
  592. } else {
  593. count = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data));
  594. if (count)
  595. goto out;
  596. }
  597. /* if we can't write at all, return -EFAULT */
  598. count = put_user(ibox_data, udata);
  599. if (count)
  600. goto out_unlock;
  601. for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
  602. int ret;
  603. ret = ctx->ops->ibox_read(ctx, &ibox_data);
  604. if (ret == 0)
  605. break;
  606. /*
  607. * at the end of the mapped area, we can fault
  608. * but still need to return the data we have
  609. * read successfully so far.
  610. */
  611. ret = put_user(ibox_data, udata);
  612. if (ret)
  613. break;
  614. }
  615. out_unlock:
  616. spu_release(ctx);
  617. out:
  618. return count;
  619. }
  620. static __poll_t spufs_ibox_poll(struct file *file, poll_table *wait)
  621. {
  622. struct spu_context *ctx = file->private_data;
  623. __poll_t mask;
  624. poll_wait(file, &ctx->ibox_wq, wait);
  625. /*
  626. * For now keep this uninterruptible and also ignore the rule
  627. * that poll should not sleep. Will be fixed later.
  628. */
  629. mutex_lock(&ctx->state_mutex);
  630. mask = ctx->ops->mbox_stat_poll(ctx, EPOLLIN | EPOLLRDNORM);
  631. spu_release(ctx);
  632. return mask;
  633. }
  634. static const struct file_operations spufs_ibox_fops = {
  635. .open = spufs_pipe_open,
  636. .read = spufs_ibox_read,
  637. .poll = spufs_ibox_poll,
  638. };
  639. static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
  640. size_t len, loff_t *pos)
  641. {
  642. struct spu_context *ctx = file->private_data;
  643. ssize_t ret;
  644. u32 ibox_stat;
  645. if (len < 4)
  646. return -EINVAL;
  647. ret = spu_acquire(ctx);
  648. if (ret)
  649. return ret;
  650. ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
  651. spu_release(ctx);
  652. if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat))
  653. return -EFAULT;
  654. return 4;
  655. }
  656. static const struct file_operations spufs_ibox_stat_fops = {
  657. .open = spufs_pipe_open,
  658. .read = spufs_ibox_stat_read,
  659. };
  660. /* low-level mailbox write */
  661. size_t spu_wbox_write(struct spu_context *ctx, u32 data)
  662. {
  663. return ctx->ops->wbox_write(ctx, data);
  664. }
  665. /* interrupt-level wbox callback function. */
  666. void spufs_wbox_callback(struct spu *spu)
  667. {
  668. struct spu_context *ctx = spu->ctx;
  669. if (ctx)
  670. wake_up_all(&ctx->wbox_wq);
  671. }
  672. /*
  673. * Write as many bytes to the interrupt mailbox as possible, until
  674. * one of the conditions becomes true:
  675. *
  676. * - the mailbox is full
  677. * - end of the user provided buffer
  678. * - end of the mapped area
  679. *
  680. * If the file is opened without O_NONBLOCK, we wait here until
  681. * space is available, but return when we have been able to
  682. * write something.
  683. */
  684. static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
  685. size_t len, loff_t *pos)
  686. {
  687. struct spu_context *ctx = file->private_data;
  688. u32 wbox_data, __user *udata = (void __user *)buf;
  689. ssize_t count;
  690. if (len < 4)
  691. return -EINVAL;
  692. if (get_user(wbox_data, udata))
  693. return -EFAULT;
  694. count = spu_acquire(ctx);
  695. if (count)
  696. goto out;
  697. /*
  698. * make sure we can at least write one element, by waiting
  699. * in case of !O_NONBLOCK
  700. */
  701. count = 0;
  702. if (file->f_flags & O_NONBLOCK) {
  703. if (!spu_wbox_write(ctx, wbox_data)) {
  704. count = -EAGAIN;
  705. goto out_unlock;
  706. }
  707. } else {
  708. count = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data));
  709. if (count)
  710. goto out;
  711. }
  712. /* write as much as possible */
  713. for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
  714. int ret;
  715. ret = get_user(wbox_data, udata);
  716. if (ret)
  717. break;
  718. ret = spu_wbox_write(ctx, wbox_data);
  719. if (ret == 0)
  720. break;
  721. }
  722. out_unlock:
  723. spu_release(ctx);
  724. out:
  725. return count;
  726. }
  727. static __poll_t spufs_wbox_poll(struct file *file, poll_table *wait)
  728. {
  729. struct spu_context *ctx = file->private_data;
  730. __poll_t mask;
  731. poll_wait(file, &ctx->wbox_wq, wait);
  732. /*
  733. * For now keep this uninterruptible and also ignore the rule
  734. * that poll should not sleep. Will be fixed later.
  735. */
  736. mutex_lock(&ctx->state_mutex);
  737. mask = ctx->ops->mbox_stat_poll(ctx, EPOLLOUT | EPOLLWRNORM);
  738. spu_release(ctx);
  739. return mask;
  740. }
  741. static const struct file_operations spufs_wbox_fops = {
  742. .open = spufs_pipe_open,
  743. .write = spufs_wbox_write,
  744. .poll = spufs_wbox_poll,
  745. };
  746. static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
  747. size_t len, loff_t *pos)
  748. {
  749. struct spu_context *ctx = file->private_data;
  750. ssize_t ret;
  751. u32 wbox_stat;
  752. if (len < 4)
  753. return -EINVAL;
  754. ret = spu_acquire(ctx);
  755. if (ret)
  756. return ret;
  757. wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
  758. spu_release(ctx);
  759. if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat))
  760. return -EFAULT;
  761. return 4;
  762. }
  763. static const struct file_operations spufs_wbox_stat_fops = {
  764. .open = spufs_pipe_open,
  765. .read = spufs_wbox_stat_read,
  766. };
  767. static int spufs_signal1_open(struct inode *inode, struct file *file)
  768. {
  769. struct spufs_inode_info *i = SPUFS_I(inode);
  770. struct spu_context *ctx = i->i_ctx;
  771. mutex_lock(&ctx->mapping_lock);
  772. file->private_data = ctx;
  773. if (!i->i_openers++)
  774. ctx->signal1 = inode->i_mapping;
  775. mutex_unlock(&ctx->mapping_lock);
  776. return nonseekable_open(inode, file);
  777. }
  778. static int
  779. spufs_signal1_release(struct inode *inode, struct file *file)
  780. {
  781. struct spufs_inode_info *i = SPUFS_I(inode);
  782. struct spu_context *ctx = i->i_ctx;
  783. mutex_lock(&ctx->mapping_lock);
  784. if (!--i->i_openers)
  785. ctx->signal1 = NULL;
  786. mutex_unlock(&ctx->mapping_lock);
  787. return 0;
  788. }
  789. static ssize_t spufs_signal1_dump(struct spu_context *ctx,
  790. struct coredump_params *cprm)
  791. {
  792. if (!ctx->csa.spu_chnlcnt_RW[3])
  793. return 0;
  794. return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[3],
  795. sizeof(ctx->csa.spu_chnldata_RW[3]));
  796. }
  797. static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf,
  798. size_t len)
  799. {
  800. if (len < sizeof(ctx->csa.spu_chnldata_RW[3]))
  801. return -EINVAL;
  802. if (!ctx->csa.spu_chnlcnt_RW[3])
  803. return 0;
  804. if (copy_to_user(buf, &ctx->csa.spu_chnldata_RW[3],
  805. sizeof(ctx->csa.spu_chnldata_RW[3])))
  806. return -EFAULT;
  807. return sizeof(ctx->csa.spu_chnldata_RW[3]);
  808. }
  809. static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
  810. size_t len, loff_t *pos)
  811. {
  812. int ret;
  813. struct spu_context *ctx = file->private_data;
  814. ret = spu_acquire_saved(ctx);
  815. if (ret)
  816. return ret;
  817. ret = __spufs_signal1_read(ctx, buf, len);
  818. spu_release_saved(ctx);
  819. return ret;
  820. }
  821. static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
  822. size_t len, loff_t *pos)
  823. {
  824. struct spu_context *ctx;
  825. ssize_t ret;
  826. u32 data;
  827. ctx = file->private_data;
  828. if (len < 4)
  829. return -EINVAL;
  830. if (copy_from_user(&data, buf, 4))
  831. return -EFAULT;
  832. ret = spu_acquire(ctx);
  833. if (ret)
  834. return ret;
  835. ctx->ops->signal1_write(ctx, data);
  836. spu_release(ctx);
  837. return 4;
  838. }
  839. static vm_fault_t
  840. spufs_signal1_mmap_fault(struct vm_fault *vmf)
  841. {
  842. #if SPUFS_SIGNAL_MAP_SIZE == 0x1000
  843. return spufs_ps_fault(vmf, 0x14000, SPUFS_SIGNAL_MAP_SIZE);
  844. #elif SPUFS_SIGNAL_MAP_SIZE == 0x10000
  845. /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
  846. * signal 1 and 2 area
  847. */
  848. return spufs_ps_fault(vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE);
  849. #else
  850. #error unsupported page size
  851. #endif
  852. }
  853. static const struct vm_operations_struct spufs_signal1_mmap_vmops = {
  854. .fault = spufs_signal1_mmap_fault,
  855. };
  856. static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
  857. {
  858. if (!(vma->vm_flags & VM_SHARED))
  859. return -EINVAL;
  860. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  861. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  862. vma->vm_ops = &spufs_signal1_mmap_vmops;
  863. return 0;
  864. }
  865. static const struct file_operations spufs_signal1_fops = {
  866. .open = spufs_signal1_open,
  867. .release = spufs_signal1_release,
  868. .read = spufs_signal1_read,
  869. .write = spufs_signal1_write,
  870. .mmap = spufs_signal1_mmap,
  871. };
  872. static const struct file_operations spufs_signal1_nosched_fops = {
  873. .open = spufs_signal1_open,
  874. .release = spufs_signal1_release,
  875. .write = spufs_signal1_write,
  876. .mmap = spufs_signal1_mmap,
  877. };
  878. static int spufs_signal2_open(struct inode *inode, struct file *file)
  879. {
  880. struct spufs_inode_info *i = SPUFS_I(inode);
  881. struct spu_context *ctx = i->i_ctx;
  882. mutex_lock(&ctx->mapping_lock);
  883. file->private_data = ctx;
  884. if (!i->i_openers++)
  885. ctx->signal2 = inode->i_mapping;
  886. mutex_unlock(&ctx->mapping_lock);
  887. return nonseekable_open(inode, file);
  888. }
  889. static int
  890. spufs_signal2_release(struct inode *inode, struct file *file)
  891. {
  892. struct spufs_inode_info *i = SPUFS_I(inode);
  893. struct spu_context *ctx = i->i_ctx;
  894. mutex_lock(&ctx->mapping_lock);
  895. if (!--i->i_openers)
  896. ctx->signal2 = NULL;
  897. mutex_unlock(&ctx->mapping_lock);
  898. return 0;
  899. }
  900. static ssize_t spufs_signal2_dump(struct spu_context *ctx,
  901. struct coredump_params *cprm)
  902. {
  903. if (!ctx->csa.spu_chnlcnt_RW[4])
  904. return 0;
  905. return spufs_dump_emit(cprm, &ctx->csa.spu_chnldata_RW[4],
  906. sizeof(ctx->csa.spu_chnldata_RW[4]));
  907. }
  908. static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf,
  909. size_t len)
  910. {
  911. if (len < sizeof(ctx->csa.spu_chnldata_RW[4]))
  912. return -EINVAL;
  913. if (!ctx->csa.spu_chnlcnt_RW[4])
  914. return 0;
  915. if (copy_to_user(buf, &ctx->csa.spu_chnldata_RW[4],
  916. sizeof(ctx->csa.spu_chnldata_RW[4])))
  917. return -EFAULT;
  918. return sizeof(ctx->csa.spu_chnldata_RW[4]);
  919. }
  920. static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
  921. size_t len, loff_t *pos)
  922. {
  923. struct spu_context *ctx = file->private_data;
  924. int ret;
  925. ret = spu_acquire_saved(ctx);
  926. if (ret)
  927. return ret;
  928. ret = __spufs_signal2_read(ctx, buf, len);
  929. spu_release_saved(ctx);
  930. return ret;
  931. }
  932. static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
  933. size_t len, loff_t *pos)
  934. {
  935. struct spu_context *ctx;
  936. ssize_t ret;
  937. u32 data;
  938. ctx = file->private_data;
  939. if (len < 4)
  940. return -EINVAL;
  941. if (copy_from_user(&data, buf, 4))
  942. return -EFAULT;
  943. ret = spu_acquire(ctx);
  944. if (ret)
  945. return ret;
  946. ctx->ops->signal2_write(ctx, data);
  947. spu_release(ctx);
  948. return 4;
  949. }
  950. #if SPUFS_MMAP_4K
  951. static vm_fault_t
  952. spufs_signal2_mmap_fault(struct vm_fault *vmf)
  953. {
  954. #if SPUFS_SIGNAL_MAP_SIZE == 0x1000
  955. return spufs_ps_fault(vmf, 0x1c000, SPUFS_SIGNAL_MAP_SIZE);
  956. #elif SPUFS_SIGNAL_MAP_SIZE == 0x10000
  957. /* For 64k pages, both signal1 and signal2 can be used to mmap the whole
  958. * signal 1 and 2 area
  959. */
  960. return spufs_ps_fault(vmf, 0x10000, SPUFS_SIGNAL_MAP_SIZE);
  961. #else
  962. #error unsupported page size
  963. #endif
  964. }
  965. static const struct vm_operations_struct spufs_signal2_mmap_vmops = {
  966. .fault = spufs_signal2_mmap_fault,
  967. };
  968. static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
  969. {
  970. if (!(vma->vm_flags & VM_SHARED))
  971. return -EINVAL;
  972. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  973. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  974. vma->vm_ops = &spufs_signal2_mmap_vmops;
  975. return 0;
  976. }
  977. #else /* SPUFS_MMAP_4K */
  978. #define spufs_signal2_mmap NULL
  979. #endif /* !SPUFS_MMAP_4K */
  980. static const struct file_operations spufs_signal2_fops = {
  981. .open = spufs_signal2_open,
  982. .release = spufs_signal2_release,
  983. .read = spufs_signal2_read,
  984. .write = spufs_signal2_write,
  985. .mmap = spufs_signal2_mmap,
  986. };
  987. static const struct file_operations spufs_signal2_nosched_fops = {
  988. .open = spufs_signal2_open,
  989. .release = spufs_signal2_release,
  990. .write = spufs_signal2_write,
  991. .mmap = spufs_signal2_mmap,
  992. };
  993. /*
  994. * This is a wrapper around DEFINE_SIMPLE_ATTRIBUTE which does the
  995. * work of acquiring (or not) the SPU context before calling through
  996. * to the actual get routine. The set routine is called directly.
  997. */
  998. #define SPU_ATTR_NOACQUIRE 0
  999. #define SPU_ATTR_ACQUIRE 1
  1000. #define SPU_ATTR_ACQUIRE_SAVED 2
  1001. #define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire) \
  1002. static int __##__get(void *data, u64 *val) \
  1003. { \
  1004. struct spu_context *ctx = data; \
  1005. int ret = 0; \
  1006. \
  1007. if (__acquire == SPU_ATTR_ACQUIRE) { \
  1008. ret = spu_acquire(ctx); \
  1009. if (ret) \
  1010. return ret; \
  1011. *val = __get(ctx); \
  1012. spu_release(ctx); \
  1013. } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \
  1014. ret = spu_acquire_saved(ctx); \
  1015. if (ret) \
  1016. return ret; \
  1017. *val = __get(ctx); \
  1018. spu_release_saved(ctx); \
  1019. } else \
  1020. *val = __get(ctx); \
  1021. \
  1022. return 0; \
  1023. } \
  1024. DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
  1025. static int spufs_signal1_type_set(void *data, u64 val)
  1026. {
  1027. struct spu_context *ctx = data;
  1028. int ret;
  1029. ret = spu_acquire(ctx);
  1030. if (ret)
  1031. return ret;
  1032. ctx->ops->signal1_type_set(ctx, val);
  1033. spu_release(ctx);
  1034. return 0;
  1035. }
  1036. static u64 spufs_signal1_type_get(struct spu_context *ctx)
  1037. {
  1038. return ctx->ops->signal1_type_get(ctx);
  1039. }
  1040. DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
  1041. spufs_signal1_type_set, "%llu\n", SPU_ATTR_ACQUIRE);
  1042. static int spufs_signal2_type_set(void *data, u64 val)
  1043. {
  1044. struct spu_context *ctx = data;
  1045. int ret;
  1046. ret = spu_acquire(ctx);
  1047. if (ret)
  1048. return ret;
  1049. ctx->ops->signal2_type_set(ctx, val);
  1050. spu_release(ctx);
  1051. return 0;
  1052. }
  1053. static u64 spufs_signal2_type_get(struct spu_context *ctx)
  1054. {
  1055. return ctx->ops->signal2_type_get(ctx);
  1056. }
  1057. DEFINE_SPUFS_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
  1058. spufs_signal2_type_set, "%llu\n", SPU_ATTR_ACQUIRE);
  1059. #if SPUFS_MMAP_4K
  1060. static vm_fault_t
  1061. spufs_mss_mmap_fault(struct vm_fault *vmf)
  1062. {
  1063. return spufs_ps_fault(vmf, 0x0000, SPUFS_MSS_MAP_SIZE);
  1064. }
  1065. static const struct vm_operations_struct spufs_mss_mmap_vmops = {
  1066. .fault = spufs_mss_mmap_fault,
  1067. };
  1068. /*
  1069. * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
  1070. */
  1071. static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
  1072. {
  1073. if (!(vma->vm_flags & VM_SHARED))
  1074. return -EINVAL;
  1075. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  1076. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  1077. vma->vm_ops = &spufs_mss_mmap_vmops;
  1078. return 0;
  1079. }
  1080. #else /* SPUFS_MMAP_4K */
  1081. #define spufs_mss_mmap NULL
  1082. #endif /* !SPUFS_MMAP_4K */
  1083. static int spufs_mss_open(struct inode *inode, struct file *file)
  1084. {
  1085. struct spufs_inode_info *i = SPUFS_I(inode);
  1086. struct spu_context *ctx = i->i_ctx;
  1087. file->private_data = i->i_ctx;
  1088. mutex_lock(&ctx->mapping_lock);
  1089. if (!i->i_openers++)
  1090. ctx->mss = inode->i_mapping;
  1091. mutex_unlock(&ctx->mapping_lock);
  1092. return nonseekable_open(inode, file);
  1093. }
  1094. static int
  1095. spufs_mss_release(struct inode *inode, struct file *file)
  1096. {
  1097. struct spufs_inode_info *i = SPUFS_I(inode);
  1098. struct spu_context *ctx = i->i_ctx;
  1099. mutex_lock(&ctx->mapping_lock);
  1100. if (!--i->i_openers)
  1101. ctx->mss = NULL;
  1102. mutex_unlock(&ctx->mapping_lock);
  1103. return 0;
  1104. }
  1105. static const struct file_operations spufs_mss_fops = {
  1106. .open = spufs_mss_open,
  1107. .release = spufs_mss_release,
  1108. .mmap = spufs_mss_mmap,
  1109. };
  1110. static vm_fault_t
  1111. spufs_psmap_mmap_fault(struct vm_fault *vmf)
  1112. {
  1113. return spufs_ps_fault(vmf, 0x0000, SPUFS_PS_MAP_SIZE);
  1114. }
  1115. static const struct vm_operations_struct spufs_psmap_mmap_vmops = {
  1116. .fault = spufs_psmap_mmap_fault,
  1117. };
  1118. /*
  1119. * mmap support for full problem state area [0x00000 - 0x1ffff].
  1120. */
  1121. static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma)
  1122. {
  1123. if (!(vma->vm_flags & VM_SHARED))
  1124. return -EINVAL;
  1125. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  1126. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  1127. vma->vm_ops = &spufs_psmap_mmap_vmops;
  1128. return 0;
  1129. }
  1130. static int spufs_psmap_open(struct inode *inode, struct file *file)
  1131. {
  1132. struct spufs_inode_info *i = SPUFS_I(inode);
  1133. struct spu_context *ctx = i->i_ctx;
  1134. mutex_lock(&ctx->mapping_lock);
  1135. file->private_data = i->i_ctx;
  1136. if (!i->i_openers++)
  1137. ctx->psmap = inode->i_mapping;
  1138. mutex_unlock(&ctx->mapping_lock);
  1139. return nonseekable_open(inode, file);
  1140. }
  1141. static int
  1142. spufs_psmap_release(struct inode *inode, struct file *file)
  1143. {
  1144. struct spufs_inode_info *i = SPUFS_I(inode);
  1145. struct spu_context *ctx = i->i_ctx;
  1146. mutex_lock(&ctx->mapping_lock);
  1147. if (!--i->i_openers)
  1148. ctx->psmap = NULL;
  1149. mutex_unlock(&ctx->mapping_lock);
  1150. return 0;
  1151. }
  1152. static const struct file_operations spufs_psmap_fops = {
  1153. .open = spufs_psmap_open,
  1154. .release = spufs_psmap_release,
  1155. .mmap = spufs_psmap_mmap,
  1156. };
  1157. #if SPUFS_MMAP_4K
  1158. static vm_fault_t
  1159. spufs_mfc_mmap_fault(struct vm_fault *vmf)
  1160. {
  1161. return spufs_ps_fault(vmf, 0x3000, SPUFS_MFC_MAP_SIZE);
  1162. }
  1163. static const struct vm_operations_struct spufs_mfc_mmap_vmops = {
  1164. .fault = spufs_mfc_mmap_fault,
  1165. };
  1166. /*
  1167. * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
  1168. */
  1169. static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
  1170. {
  1171. if (!(vma->vm_flags & VM_SHARED))
  1172. return -EINVAL;
  1173. vm_flags_set(vma, VM_IO | VM_PFNMAP);
  1174. vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  1175. vma->vm_ops = &spufs_mfc_mmap_vmops;
  1176. return 0;
  1177. }
  1178. #else /* SPUFS_MMAP_4K */
  1179. #define spufs_mfc_mmap NULL
  1180. #endif /* !SPUFS_MMAP_4K */
  1181. static int spufs_mfc_open(struct inode *inode, struct file *file)
  1182. {
  1183. struct spufs_inode_info *i = SPUFS_I(inode);
  1184. struct spu_context *ctx = i->i_ctx;
  1185. /* we don't want to deal with DMA into other processes */
  1186. if (ctx->owner != current->mm)
  1187. return -EINVAL;
  1188. if (atomic_read(&inode->i_count) != 1)
  1189. return -EBUSY;
  1190. mutex_lock(&ctx->mapping_lock);
  1191. file->private_data = ctx;
  1192. if (!i->i_openers++)
  1193. ctx->mfc = inode->i_mapping;
  1194. mutex_unlock(&ctx->mapping_lock);
  1195. return nonseekable_open(inode, file);
  1196. }
  1197. static int
  1198. spufs_mfc_release(struct inode *inode, struct file *file)
  1199. {
  1200. struct spufs_inode_info *i = SPUFS_I(inode);
  1201. struct spu_context *ctx = i->i_ctx;
  1202. mutex_lock(&ctx->mapping_lock);
  1203. if (!--i->i_openers)
  1204. ctx->mfc = NULL;
  1205. mutex_unlock(&ctx->mapping_lock);
  1206. return 0;
  1207. }
  1208. /* interrupt-level mfc callback function. */
  1209. void spufs_mfc_callback(struct spu *spu)
  1210. {
  1211. struct spu_context *ctx = spu->ctx;
  1212. if (ctx)
  1213. wake_up_all(&ctx->mfc_wq);
  1214. }
  1215. static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status)
  1216. {
  1217. /* See if there is one tag group is complete */
  1218. /* FIXME we need locking around tagwait */
  1219. *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait;
  1220. ctx->tagwait &= ~*status;
  1221. if (*status)
  1222. return 1;
  1223. /* enable interrupt waiting for any tag group,
  1224. may silently fail if interrupts are already enabled */
  1225. ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
  1226. return 0;
  1227. }
  1228. static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
  1229. size_t size, loff_t *pos)
  1230. {
  1231. struct spu_context *ctx = file->private_data;
  1232. int ret = -EINVAL;
  1233. u32 status;
  1234. if (size != 4)
  1235. goto out;
  1236. ret = spu_acquire(ctx);
  1237. if (ret)
  1238. return ret;
  1239. ret = -EINVAL;
  1240. if (file->f_flags & O_NONBLOCK) {
  1241. status = ctx->ops->read_mfc_tagstatus(ctx);
  1242. if (!(status & ctx->tagwait))
  1243. ret = -EAGAIN;
  1244. else
  1245. /* XXX(hch): shouldn't we clear ret here? */
  1246. ctx->tagwait &= ~status;
  1247. } else {
  1248. ret = spufs_wait(ctx->mfc_wq,
  1249. spufs_read_mfc_tagstatus(ctx, &status));
  1250. if (ret)
  1251. goto out;
  1252. }
  1253. spu_release(ctx);
  1254. ret = 4;
  1255. if (copy_to_user(buffer, &status, 4))
  1256. ret = -EFAULT;
  1257. out:
  1258. return ret;
  1259. }
  1260. static int spufs_check_valid_dma(struct mfc_dma_command *cmd)
  1261. {
  1262. pr_debug("queueing DMA %x %llx %x %x %x\n", cmd->lsa,
  1263. cmd->ea, cmd->size, cmd->tag, cmd->cmd);
  1264. switch (cmd->cmd) {
  1265. case MFC_PUT_CMD:
  1266. case MFC_PUTF_CMD:
  1267. case MFC_PUTB_CMD:
  1268. case MFC_GET_CMD:
  1269. case MFC_GETF_CMD:
  1270. case MFC_GETB_CMD:
  1271. break;
  1272. default:
  1273. pr_debug("invalid DMA opcode %x\n", cmd->cmd);
  1274. return -EIO;
  1275. }
  1276. if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) {
  1277. pr_debug("invalid DMA alignment, ea %llx lsa %x\n",
  1278. cmd->ea, cmd->lsa);
  1279. return -EIO;
  1280. }
  1281. switch (cmd->size & 0xf) {
  1282. case 1:
  1283. break;
  1284. case 2:
  1285. if (cmd->lsa & 1)
  1286. goto error;
  1287. break;
  1288. case 4:
  1289. if (cmd->lsa & 3)
  1290. goto error;
  1291. break;
  1292. case 8:
  1293. if (cmd->lsa & 7)
  1294. goto error;
  1295. break;
  1296. case 0:
  1297. if (cmd->lsa & 15)
  1298. goto error;
  1299. break;
  1300. error:
  1301. default:
  1302. pr_debug("invalid DMA alignment %x for size %x\n",
  1303. cmd->lsa & 0xf, cmd->size);
  1304. return -EIO;
  1305. }
  1306. if (cmd->size > 16 * 1024) {
  1307. pr_debug("invalid DMA size %x\n", cmd->size);
  1308. return -EIO;
  1309. }
  1310. if (cmd->tag & 0xfff0) {
  1311. /* we reserve the higher tag numbers for kernel use */
  1312. pr_debug("invalid DMA tag\n");
  1313. return -EIO;
  1314. }
  1315. if (cmd->class) {
  1316. /* not supported in this version */
  1317. pr_debug("invalid DMA class\n");
  1318. return -EIO;
  1319. }
  1320. return 0;
  1321. }
  1322. static int spu_send_mfc_command(struct spu_context *ctx,
  1323. struct mfc_dma_command cmd,
  1324. int *error)
  1325. {
  1326. *error = ctx->ops->send_mfc_command(ctx, &cmd);
  1327. if (*error == -EAGAIN) {
  1328. /* wait for any tag group to complete
  1329. so we have space for the new command */
  1330. ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
  1331. /* try again, because the queue might be
  1332. empty again */
  1333. *error = ctx->ops->send_mfc_command(ctx, &cmd);
  1334. if (*error == -EAGAIN)
  1335. return 0;
  1336. }
  1337. return 1;
  1338. }
  1339. static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
  1340. size_t size, loff_t *pos)
  1341. {
  1342. struct spu_context *ctx = file->private_data;
  1343. struct mfc_dma_command cmd;
  1344. int ret = -EINVAL;
  1345. if (size != sizeof cmd)
  1346. goto out;
  1347. ret = -EFAULT;
  1348. if (copy_from_user(&cmd, buffer, sizeof cmd))
  1349. goto out;
  1350. ret = spufs_check_valid_dma(&cmd);
  1351. if (ret)
  1352. goto out;
  1353. ret = spu_acquire(ctx);
  1354. if (ret)
  1355. goto out;
  1356. ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
  1357. if (ret)
  1358. goto out;
  1359. if (file->f_flags & O_NONBLOCK) {
  1360. ret = ctx->ops->send_mfc_command(ctx, &cmd);
  1361. } else {
  1362. int status;
  1363. ret = spufs_wait(ctx->mfc_wq,
  1364. spu_send_mfc_command(ctx, cmd, &status));
  1365. if (ret)
  1366. goto out;
  1367. if (status)
  1368. ret = status;
  1369. }
  1370. if (ret)
  1371. goto out_unlock;
  1372. ctx->tagwait |= 1 << cmd.tag;
  1373. ret = size;
  1374. out_unlock:
  1375. spu_release(ctx);
  1376. out:
  1377. return ret;
  1378. }
  1379. static __poll_t spufs_mfc_poll(struct file *file,poll_table *wait)
  1380. {
  1381. struct spu_context *ctx = file->private_data;
  1382. u32 free_elements, tagstatus;
  1383. __poll_t mask;
  1384. poll_wait(file, &ctx->mfc_wq, wait);
  1385. /*
  1386. * For now keep this uninterruptible and also ignore the rule
  1387. * that poll should not sleep. Will be fixed later.
  1388. */
  1389. mutex_lock(&ctx->state_mutex);
  1390. ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
  1391. free_elements = ctx->ops->get_mfc_free_elements(ctx);
  1392. tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
  1393. spu_release(ctx);
  1394. mask = 0;
  1395. if (free_elements & 0xffff)
  1396. mask |= EPOLLOUT | EPOLLWRNORM;
  1397. if (tagstatus & ctx->tagwait)
  1398. mask |= EPOLLIN | EPOLLRDNORM;
  1399. pr_debug("%s: free %d tagstatus %d tagwait %d\n", __func__,
  1400. free_elements, tagstatus, ctx->tagwait);
  1401. return mask;
  1402. }
  1403. static int spufs_mfc_flush(struct file *file, fl_owner_t id)
  1404. {
  1405. struct spu_context *ctx = file->private_data;
  1406. int ret;
  1407. ret = spu_acquire(ctx);
  1408. if (ret)
  1409. return ret;
  1410. spu_release(ctx);
  1411. return 0;
  1412. }
  1413. static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int datasync)
  1414. {
  1415. struct inode *inode = file_inode(file);
  1416. int err = file_write_and_wait_range(file, start, end);
  1417. if (!err) {
  1418. inode_lock(inode);
  1419. err = spufs_mfc_flush(file, NULL);
  1420. inode_unlock(inode);
  1421. }
  1422. return err;
  1423. }
  1424. static const struct file_operations spufs_mfc_fops = {
  1425. .open = spufs_mfc_open,
  1426. .release = spufs_mfc_release,
  1427. .read = spufs_mfc_read,
  1428. .write = spufs_mfc_write,
  1429. .poll = spufs_mfc_poll,
  1430. .flush = spufs_mfc_flush,
  1431. .fsync = spufs_mfc_fsync,
  1432. .mmap = spufs_mfc_mmap,
  1433. };
  1434. static int spufs_npc_set(void *data, u64 val)
  1435. {
  1436. struct spu_context *ctx = data;
  1437. int ret;
  1438. ret = spu_acquire(ctx);
  1439. if (ret)
  1440. return ret;
  1441. ctx->ops->npc_write(ctx, val);
  1442. spu_release(ctx);
  1443. return 0;
  1444. }
  1445. static u64 spufs_npc_get(struct spu_context *ctx)
  1446. {
  1447. return ctx->ops->npc_read(ctx);
  1448. }
  1449. DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
  1450. "0x%llx\n", SPU_ATTR_ACQUIRE);
  1451. static int spufs_decr_set(void *data, u64 val)
  1452. {
  1453. struct spu_context *ctx = data;
  1454. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1455. int ret;
  1456. ret = spu_acquire_saved(ctx);
  1457. if (ret)
  1458. return ret;
  1459. lscsa->decr.slot[0] = (u32) val;
  1460. spu_release_saved(ctx);
  1461. return 0;
  1462. }
  1463. static u64 spufs_decr_get(struct spu_context *ctx)
  1464. {
  1465. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1466. return lscsa->decr.slot[0];
  1467. }
  1468. DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
  1469. "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED);
  1470. static int spufs_decr_status_set(void *data, u64 val)
  1471. {
  1472. struct spu_context *ctx = data;
  1473. int ret;
  1474. ret = spu_acquire_saved(ctx);
  1475. if (ret)
  1476. return ret;
  1477. if (val)
  1478. ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
  1479. else
  1480. ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING;
  1481. spu_release_saved(ctx);
  1482. return 0;
  1483. }
  1484. static u64 spufs_decr_status_get(struct spu_context *ctx)
  1485. {
  1486. if (ctx->csa.priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING)
  1487. return SPU_DECR_STATUS_RUNNING;
  1488. else
  1489. return 0;
  1490. }
  1491. DEFINE_SPUFS_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
  1492. spufs_decr_status_set, "0x%llx\n",
  1493. SPU_ATTR_ACQUIRE_SAVED);
  1494. static int spufs_event_mask_set(void *data, u64 val)
  1495. {
  1496. struct spu_context *ctx = data;
  1497. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1498. int ret;
  1499. ret = spu_acquire_saved(ctx);
  1500. if (ret)
  1501. return ret;
  1502. lscsa->event_mask.slot[0] = (u32) val;
  1503. spu_release_saved(ctx);
  1504. return 0;
  1505. }
  1506. static u64 spufs_event_mask_get(struct spu_context *ctx)
  1507. {
  1508. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1509. return lscsa->event_mask.slot[0];
  1510. }
  1511. DEFINE_SPUFS_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
  1512. spufs_event_mask_set, "0x%llx\n",
  1513. SPU_ATTR_ACQUIRE_SAVED);
  1514. static u64 spufs_event_status_get(struct spu_context *ctx)
  1515. {
  1516. struct spu_state *state = &ctx->csa;
  1517. u64 stat;
  1518. stat = state->spu_chnlcnt_RW[0];
  1519. if (stat)
  1520. return state->spu_chnldata_RW[0];
  1521. return 0;
  1522. }
  1523. DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
  1524. NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
  1525. static int spufs_srr0_set(void *data, u64 val)
  1526. {
  1527. struct spu_context *ctx = data;
  1528. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1529. int ret;
  1530. ret = spu_acquire_saved(ctx);
  1531. if (ret)
  1532. return ret;
  1533. lscsa->srr0.slot[0] = (u32) val;
  1534. spu_release_saved(ctx);
  1535. return 0;
  1536. }
  1537. static u64 spufs_srr0_get(struct spu_context *ctx)
  1538. {
  1539. struct spu_lscsa *lscsa = ctx->csa.lscsa;
  1540. return lscsa->srr0.slot[0];
  1541. }
  1542. DEFINE_SPUFS_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
  1543. "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
  1544. static u64 spufs_id_get(struct spu_context *ctx)
  1545. {
  1546. u64 num;
  1547. if (ctx->state == SPU_STATE_RUNNABLE)
  1548. num = ctx->spu->number;
  1549. else
  1550. num = (unsigned int)-1;
  1551. return num;
  1552. }
  1553. DEFINE_SPUFS_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n",
  1554. SPU_ATTR_ACQUIRE)
  1555. static u64 spufs_object_id_get(struct spu_context *ctx)
  1556. {
  1557. /* FIXME: Should there really be no locking here? */
  1558. return ctx->object_id;
  1559. }
  1560. static int spufs_object_id_set(void *data, u64 id)
  1561. {
  1562. struct spu_context *ctx = data;
  1563. ctx->object_id = id;
  1564. return 0;
  1565. }
  1566. DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
  1567. spufs_object_id_set, "0x%llx\n", SPU_ATTR_NOACQUIRE);
  1568. static u64 spufs_lslr_get(struct spu_context *ctx)
  1569. {
  1570. return ctx->csa.priv2.spu_lslr_RW;
  1571. }
  1572. DEFINE_SPUFS_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n",
  1573. SPU_ATTR_ACQUIRE_SAVED);
  1574. static int spufs_info_open(struct inode *inode, struct file *file)
  1575. {
  1576. struct spufs_inode_info *i = SPUFS_I(inode);
  1577. struct spu_context *ctx = i->i_ctx;
  1578. file->private_data = ctx;
  1579. return 0;
  1580. }
  1581. static int spufs_caps_show(struct seq_file *s, void *private)
  1582. {
  1583. struct spu_context *ctx = s->private;
  1584. if (!(ctx->flags & SPU_CREATE_NOSCHED))
  1585. seq_puts(s, "sched\n");
  1586. if (!(ctx->flags & SPU_CREATE_ISOLATE))
  1587. seq_puts(s, "step\n");
  1588. return 0;
  1589. }
  1590. static int spufs_caps_open(struct inode *inode, struct file *file)
  1591. {
  1592. return single_open(file, spufs_caps_show, SPUFS_I(inode)->i_ctx);
  1593. }
  1594. static const struct file_operations spufs_caps_fops = {
  1595. .open = spufs_caps_open,
  1596. .read = seq_read,
  1597. .llseek = seq_lseek,
  1598. .release = single_release,
  1599. };
  1600. static ssize_t spufs_mbox_info_dump(struct spu_context *ctx,
  1601. struct coredump_params *cprm)
  1602. {
  1603. if (!(ctx->csa.prob.mb_stat_R & 0x0000ff))
  1604. return 0;
  1605. return spufs_dump_emit(cprm, &ctx->csa.prob.pu_mb_R,
  1606. sizeof(ctx->csa.prob.pu_mb_R));
  1607. }
  1608. static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
  1609. size_t len, loff_t *pos)
  1610. {
  1611. struct spu_context *ctx = file->private_data;
  1612. u32 stat, data;
  1613. int ret;
  1614. ret = spu_acquire_saved(ctx);
  1615. if (ret)
  1616. return ret;
  1617. spin_lock(&ctx->csa.register_lock);
  1618. stat = ctx->csa.prob.mb_stat_R;
  1619. data = ctx->csa.prob.pu_mb_R;
  1620. spin_unlock(&ctx->csa.register_lock);
  1621. spu_release_saved(ctx);
  1622. /* EOF if there's no entry in the mbox */
  1623. if (!(stat & 0x0000ff))
  1624. return 0;
  1625. return simple_read_from_buffer(buf, len, pos, &data, sizeof(data));
  1626. }
  1627. static const struct file_operations spufs_mbox_info_fops = {
  1628. .open = spufs_info_open,
  1629. .read = spufs_mbox_info_read,
  1630. .llseek = generic_file_llseek,
  1631. };
  1632. static ssize_t spufs_ibox_info_dump(struct spu_context *ctx,
  1633. struct coredump_params *cprm)
  1634. {
  1635. if (!(ctx->csa.prob.mb_stat_R & 0xff0000))
  1636. return 0;
  1637. return spufs_dump_emit(cprm, &ctx->csa.priv2.puint_mb_R,
  1638. sizeof(ctx->csa.priv2.puint_mb_R));
  1639. }
  1640. static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
  1641. size_t len, loff_t *pos)
  1642. {
  1643. struct spu_context *ctx = file->private_data;
  1644. u32 stat, data;
  1645. int ret;
  1646. ret = spu_acquire_saved(ctx);
  1647. if (ret)
  1648. return ret;
  1649. spin_lock(&ctx->csa.register_lock);
  1650. stat = ctx->csa.prob.mb_stat_R;
  1651. data = ctx->csa.priv2.puint_mb_R;
  1652. spin_unlock(&ctx->csa.register_lock);
  1653. spu_release_saved(ctx);
  1654. /* EOF if there's no entry in the ibox */
  1655. if (!(stat & 0xff0000))
  1656. return 0;
  1657. return simple_read_from_buffer(buf, len, pos, &data, sizeof(data));
  1658. }
  1659. static const struct file_operations spufs_ibox_info_fops = {
  1660. .open = spufs_info_open,
  1661. .read = spufs_ibox_info_read,
  1662. .llseek = generic_file_llseek,
  1663. };
  1664. static size_t spufs_wbox_info_cnt(struct spu_context *ctx)
  1665. {
  1666. return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32);
  1667. }
  1668. static ssize_t spufs_wbox_info_dump(struct spu_context *ctx,
  1669. struct coredump_params *cprm)
  1670. {
  1671. return spufs_dump_emit(cprm, &ctx->csa.spu_mailbox_data,
  1672. spufs_wbox_info_cnt(ctx));
  1673. }
  1674. static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
  1675. size_t len, loff_t *pos)
  1676. {
  1677. struct spu_context *ctx = file->private_data;
  1678. u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)];
  1679. int ret, count;
  1680. ret = spu_acquire_saved(ctx);
  1681. if (ret)
  1682. return ret;
  1683. spin_lock(&ctx->csa.register_lock);
  1684. count = spufs_wbox_info_cnt(ctx);
  1685. memcpy(&data, &ctx->csa.spu_mailbox_data, sizeof(data));
  1686. spin_unlock(&ctx->csa.register_lock);
  1687. spu_release_saved(ctx);
  1688. return simple_read_from_buffer(buf, len, pos, &data,
  1689. count * sizeof(u32));
  1690. }
  1691. static const struct file_operations spufs_wbox_info_fops = {
  1692. .open = spufs_info_open,
  1693. .read = spufs_wbox_info_read,
  1694. .llseek = generic_file_llseek,
  1695. };
  1696. static void spufs_get_dma_info(struct spu_context *ctx,
  1697. struct spu_dma_info *info)
  1698. {
  1699. int i;
  1700. info->dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW;
  1701. info->dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0];
  1702. info->dma_info_status = ctx->csa.spu_chnldata_RW[24];
  1703. info->dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25];
  1704. info->dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27];
  1705. for (i = 0; i < 16; i++) {
  1706. struct mfc_cq_sr *qp = &info->dma_info_command_data[i];
  1707. struct mfc_cq_sr *spuqp = &ctx->csa.priv2.spuq[i];
  1708. qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW;
  1709. qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW;
  1710. qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW;
  1711. qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW;
  1712. }
  1713. }
  1714. static ssize_t spufs_dma_info_dump(struct spu_context *ctx,
  1715. struct coredump_params *cprm)
  1716. {
  1717. struct spu_dma_info info;
  1718. spufs_get_dma_info(ctx, &info);
  1719. return spufs_dump_emit(cprm, &info, sizeof(info));
  1720. }
  1721. static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
  1722. size_t len, loff_t *pos)
  1723. {
  1724. struct spu_context *ctx = file->private_data;
  1725. struct spu_dma_info info;
  1726. int ret;
  1727. ret = spu_acquire_saved(ctx);
  1728. if (ret)
  1729. return ret;
  1730. spin_lock(&ctx->csa.register_lock);
  1731. spufs_get_dma_info(ctx, &info);
  1732. spin_unlock(&ctx->csa.register_lock);
  1733. spu_release_saved(ctx);
  1734. return simple_read_from_buffer(buf, len, pos, &info,
  1735. sizeof(info));
  1736. }
  1737. static const struct file_operations spufs_dma_info_fops = {
  1738. .open = spufs_info_open,
  1739. .read = spufs_dma_info_read,
  1740. };
  1741. static void spufs_get_proxydma_info(struct spu_context *ctx,
  1742. struct spu_proxydma_info *info)
  1743. {
  1744. int i;
  1745. info->proxydma_info_type = ctx->csa.prob.dma_querytype_RW;
  1746. info->proxydma_info_mask = ctx->csa.prob.dma_querymask_RW;
  1747. info->proxydma_info_status = ctx->csa.prob.dma_tagstatus_R;
  1748. for (i = 0; i < 8; i++) {
  1749. struct mfc_cq_sr *qp = &info->proxydma_info_command_data[i];
  1750. struct mfc_cq_sr *puqp = &ctx->csa.priv2.puq[i];
  1751. qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW;
  1752. qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW;
  1753. qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW;
  1754. qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW;
  1755. }
  1756. }
  1757. static ssize_t spufs_proxydma_info_dump(struct spu_context *ctx,
  1758. struct coredump_params *cprm)
  1759. {
  1760. struct spu_proxydma_info info;
  1761. spufs_get_proxydma_info(ctx, &info);
  1762. return spufs_dump_emit(cprm, &info, sizeof(info));
  1763. }
  1764. static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
  1765. size_t len, loff_t *pos)
  1766. {
  1767. struct spu_context *ctx = file->private_data;
  1768. struct spu_proxydma_info info;
  1769. int ret;
  1770. if (len < sizeof(info))
  1771. return -EINVAL;
  1772. ret = spu_acquire_saved(ctx);
  1773. if (ret)
  1774. return ret;
  1775. spin_lock(&ctx->csa.register_lock);
  1776. spufs_get_proxydma_info(ctx, &info);
  1777. spin_unlock(&ctx->csa.register_lock);
  1778. spu_release_saved(ctx);
  1779. return simple_read_from_buffer(buf, len, pos, &info,
  1780. sizeof(info));
  1781. }
  1782. static const struct file_operations spufs_proxydma_info_fops = {
  1783. .open = spufs_info_open,
  1784. .read = spufs_proxydma_info_read,
  1785. };
  1786. static int spufs_show_tid(struct seq_file *s, void *private)
  1787. {
  1788. struct spu_context *ctx = s->private;
  1789. seq_printf(s, "%d\n", ctx->tid);
  1790. return 0;
  1791. }
  1792. static int spufs_tid_open(struct inode *inode, struct file *file)
  1793. {
  1794. return single_open(file, spufs_show_tid, SPUFS_I(inode)->i_ctx);
  1795. }
  1796. static const struct file_operations spufs_tid_fops = {
  1797. .open = spufs_tid_open,
  1798. .read = seq_read,
  1799. .llseek = seq_lseek,
  1800. .release = single_release,
  1801. };
  1802. static const char *ctx_state_names[] = {
  1803. "user", "system", "iowait", "loaded"
  1804. };
  1805. static unsigned long long spufs_acct_time(struct spu_context *ctx,
  1806. enum spu_utilization_state state)
  1807. {
  1808. unsigned long long time = ctx->stats.times[state];
  1809. /*
  1810. * In general, utilization statistics are updated by the controlling
  1811. * thread as the spu context moves through various well defined
  1812. * state transitions, but if the context is lazily loaded its
  1813. * utilization statistics are not updated as the controlling thread
  1814. * is not tightly coupled with the execution of the spu context. We
  1815. * calculate and apply the time delta from the last recorded state
  1816. * of the spu context.
  1817. */
  1818. if (ctx->spu && ctx->stats.util_state == state) {
  1819. time += ktime_get_ns() - ctx->stats.tstamp;
  1820. }
  1821. return time / NSEC_PER_MSEC;
  1822. }
  1823. static unsigned long long spufs_slb_flts(struct spu_context *ctx)
  1824. {
  1825. unsigned long long slb_flts = ctx->stats.slb_flt;
  1826. if (ctx->state == SPU_STATE_RUNNABLE) {
  1827. slb_flts += (ctx->spu->stats.slb_flt -
  1828. ctx->stats.slb_flt_base);
  1829. }
  1830. return slb_flts;
  1831. }
  1832. static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
  1833. {
  1834. unsigned long long class2_intrs = ctx->stats.class2_intr;
  1835. if (ctx->state == SPU_STATE_RUNNABLE) {
  1836. class2_intrs += (ctx->spu->stats.class2_intr -
  1837. ctx->stats.class2_intr_base);
  1838. }
  1839. return class2_intrs;
  1840. }
  1841. static int spufs_show_stat(struct seq_file *s, void *private)
  1842. {
  1843. struct spu_context *ctx = s->private;
  1844. int ret;
  1845. ret = spu_acquire(ctx);
  1846. if (ret)
  1847. return ret;
  1848. seq_printf(s, "%s %llu %llu %llu %llu "
  1849. "%llu %llu %llu %llu %llu %llu %llu %llu\n",
  1850. ctx_state_names[ctx->stats.util_state],
  1851. spufs_acct_time(ctx, SPU_UTIL_USER),
  1852. spufs_acct_time(ctx, SPU_UTIL_SYSTEM),
  1853. spufs_acct_time(ctx, SPU_UTIL_IOWAIT),
  1854. spufs_acct_time(ctx, SPU_UTIL_IDLE_LOADED),
  1855. ctx->stats.vol_ctx_switch,
  1856. ctx->stats.invol_ctx_switch,
  1857. spufs_slb_flts(ctx),
  1858. ctx->stats.hash_flt,
  1859. ctx->stats.min_flt,
  1860. ctx->stats.maj_flt,
  1861. spufs_class2_intrs(ctx),
  1862. ctx->stats.libassist);
  1863. spu_release(ctx);
  1864. return 0;
  1865. }
  1866. static int spufs_stat_open(struct inode *inode, struct file *file)
  1867. {
  1868. return single_open(file, spufs_show_stat, SPUFS_I(inode)->i_ctx);
  1869. }
  1870. static const struct file_operations spufs_stat_fops = {
  1871. .open = spufs_stat_open,
  1872. .read = seq_read,
  1873. .llseek = seq_lseek,
  1874. .release = single_release,
  1875. };
  1876. static inline int spufs_switch_log_used(struct spu_context *ctx)
  1877. {
  1878. return (ctx->switch_log->head - ctx->switch_log->tail) %
  1879. SWITCH_LOG_BUFSIZE;
  1880. }
  1881. static inline int spufs_switch_log_avail(struct spu_context *ctx)
  1882. {
  1883. return SWITCH_LOG_BUFSIZE - spufs_switch_log_used(ctx);
  1884. }
  1885. static int spufs_switch_log_open(struct inode *inode, struct file *file)
  1886. {
  1887. struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
  1888. int rc;
  1889. rc = spu_acquire(ctx);
  1890. if (rc)
  1891. return rc;
  1892. if (ctx->switch_log) {
  1893. rc = -EBUSY;
  1894. goto out;
  1895. }
  1896. ctx->switch_log = kmalloc(struct_size(ctx->switch_log, log,
  1897. SWITCH_LOG_BUFSIZE), GFP_KERNEL);
  1898. if (!ctx->switch_log) {
  1899. rc = -ENOMEM;
  1900. goto out;
  1901. }
  1902. ctx->switch_log->head = ctx->switch_log->tail = 0;
  1903. init_waitqueue_head(&ctx->switch_log->wait);
  1904. rc = 0;
  1905. out:
  1906. spu_release(ctx);
  1907. return rc;
  1908. }
  1909. static int spufs_switch_log_release(struct inode *inode, struct file *file)
  1910. {
  1911. struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
  1912. int rc;
  1913. rc = spu_acquire(ctx);
  1914. if (rc)
  1915. return rc;
  1916. kfree(ctx->switch_log);
  1917. ctx->switch_log = NULL;
  1918. spu_release(ctx);
  1919. return 0;
  1920. }
  1921. static int switch_log_sprint(struct spu_context *ctx, char *tbuf, int n)
  1922. {
  1923. struct switch_log_entry *p;
  1924. p = ctx->switch_log->log + ctx->switch_log->tail % SWITCH_LOG_BUFSIZE;
  1925. return snprintf(tbuf, n, "%llu.%09u %d %u %u %llu\n",
  1926. (unsigned long long) p->tstamp.tv_sec,
  1927. (unsigned int) p->tstamp.tv_nsec,
  1928. p->spu_id,
  1929. (unsigned int) p->type,
  1930. (unsigned int) p->val,
  1931. (unsigned long long) p->timebase);
  1932. }
  1933. static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
  1934. size_t len, loff_t *ppos)
  1935. {
  1936. struct inode *inode = file_inode(file);
  1937. struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
  1938. int error = 0, cnt = 0;
  1939. if (!buf)
  1940. return -EINVAL;
  1941. error = spu_acquire(ctx);
  1942. if (error)
  1943. return error;
  1944. while (cnt < len) {
  1945. char tbuf[128];
  1946. int width;
  1947. if (spufs_switch_log_used(ctx) == 0) {
  1948. if (cnt > 0) {
  1949. /* If there's data ready to go, we can
  1950. * just return straight away */
  1951. break;
  1952. } else if (file->f_flags & O_NONBLOCK) {
  1953. error = -EAGAIN;
  1954. break;
  1955. } else {
  1956. /* spufs_wait will drop the mutex and
  1957. * re-acquire, but since we're in read(), the
  1958. * file cannot be _released (and so
  1959. * ctx->switch_log is stable).
  1960. */
  1961. error = spufs_wait(ctx->switch_log->wait,
  1962. spufs_switch_log_used(ctx) > 0);
  1963. /* On error, spufs_wait returns without the
  1964. * state mutex held */
  1965. if (error)
  1966. return error;
  1967. /* We may have had entries read from underneath
  1968. * us while we dropped the mutex in spufs_wait,
  1969. * so re-check */
  1970. if (spufs_switch_log_used(ctx) == 0)
  1971. continue;
  1972. }
  1973. }
  1974. width = switch_log_sprint(ctx, tbuf, sizeof(tbuf));
  1975. if (width < len)
  1976. ctx->switch_log->tail =
  1977. (ctx->switch_log->tail + 1) %
  1978. SWITCH_LOG_BUFSIZE;
  1979. else
  1980. /* If the record is greater than space available return
  1981. * partial buffer (so far) */
  1982. break;
  1983. error = copy_to_user(buf + cnt, tbuf, width);
  1984. if (error)
  1985. break;
  1986. cnt += width;
  1987. }
  1988. spu_release(ctx);
  1989. return cnt == 0 ? error : cnt;
  1990. }
  1991. static __poll_t spufs_switch_log_poll(struct file *file, poll_table *wait)
  1992. {
  1993. struct inode *inode = file_inode(file);
  1994. struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
  1995. __poll_t mask = 0;
  1996. int rc;
  1997. poll_wait(file, &ctx->switch_log->wait, wait);
  1998. rc = spu_acquire(ctx);
  1999. if (rc)
  2000. return rc;
  2001. if (spufs_switch_log_used(ctx) > 0)
  2002. mask |= EPOLLIN;
  2003. spu_release(ctx);
  2004. return mask;
  2005. }
  2006. static const struct file_operations spufs_switch_log_fops = {
  2007. .open = spufs_switch_log_open,
  2008. .read = spufs_switch_log_read,
  2009. .poll = spufs_switch_log_poll,
  2010. .release = spufs_switch_log_release,
  2011. };
  2012. /**
  2013. * Log a context switch event to a switch log reader.
  2014. *
  2015. * Must be called with ctx->state_mutex held.
  2016. */
  2017. void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx,
  2018. u32 type, u32 val)
  2019. {
  2020. if (!ctx->switch_log)
  2021. return;
  2022. if (spufs_switch_log_avail(ctx) > 1) {
  2023. struct switch_log_entry *p;
  2024. p = ctx->switch_log->log + ctx->switch_log->head;
  2025. ktime_get_ts64(&p->tstamp);
  2026. p->timebase = get_tb();
  2027. p->spu_id = spu ? spu->number : -1;
  2028. p->type = type;
  2029. p->val = val;
  2030. ctx->switch_log->head =
  2031. (ctx->switch_log->head + 1) % SWITCH_LOG_BUFSIZE;
  2032. }
  2033. wake_up(&ctx->switch_log->wait);
  2034. }
  2035. static int spufs_show_ctx(struct seq_file *s, void *private)
  2036. {
  2037. struct spu_context *ctx = s->private;
  2038. u64 mfc_control_RW;
  2039. mutex_lock(&ctx->state_mutex);
  2040. if (ctx->spu) {
  2041. struct spu *spu = ctx->spu;
  2042. struct spu_priv2 __iomem *priv2 = spu->priv2;
  2043. spin_lock_irq(&spu->register_lock);
  2044. mfc_control_RW = in_be64(&priv2->mfc_control_RW);
  2045. spin_unlock_irq(&spu->register_lock);
  2046. } else {
  2047. struct spu_state *csa = &ctx->csa;
  2048. mfc_control_RW = csa->priv2.mfc_control_RW;
  2049. }
  2050. seq_printf(s, "%c flgs(%lx) sflgs(%lx) pri(%d) ts(%d) spu(%02d)"
  2051. " %c %llx %llx %llx %llx %x %x\n",
  2052. ctx->state == SPU_STATE_SAVED ? 'S' : 'R',
  2053. ctx->flags,
  2054. ctx->sched_flags,
  2055. ctx->prio,
  2056. ctx->time_slice,
  2057. ctx->spu ? ctx->spu->number : -1,
  2058. !list_empty(&ctx->rq) ? 'q' : ' ',
  2059. ctx->csa.class_0_pending,
  2060. ctx->csa.class_0_dar,
  2061. ctx->csa.class_1_dsisr,
  2062. mfc_control_RW,
  2063. ctx->ops->runcntl_read(ctx),
  2064. ctx->ops->status_read(ctx));
  2065. mutex_unlock(&ctx->state_mutex);
  2066. return 0;
  2067. }
  2068. static int spufs_ctx_open(struct inode *inode, struct file *file)
  2069. {
  2070. return single_open(file, spufs_show_ctx, SPUFS_I(inode)->i_ctx);
  2071. }
  2072. static const struct file_operations spufs_ctx_fops = {
  2073. .open = spufs_ctx_open,
  2074. .read = seq_read,
  2075. .llseek = seq_lseek,
  2076. .release = single_release,
  2077. };
  2078. const struct spufs_tree_descr spufs_dir_contents[] = {
  2079. { "capabilities", &spufs_caps_fops, 0444, },
  2080. { "mem", &spufs_mem_fops, 0666, LS_SIZE, },
  2081. { "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), },
  2082. { "mbox", &spufs_mbox_fops, 0444, },
  2083. { "ibox", &spufs_ibox_fops, 0444, },
  2084. { "wbox", &spufs_wbox_fops, 0222, },
  2085. { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), },
  2086. { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), },
  2087. { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), },
  2088. { "signal1", &spufs_signal1_fops, 0666, },
  2089. { "signal2", &spufs_signal2_fops, 0666, },
  2090. { "signal1_type", &spufs_signal1_type, 0666, },
  2091. { "signal2_type", &spufs_signal2_type, 0666, },
  2092. { "cntl", &spufs_cntl_fops, 0666, },
  2093. { "fpcr", &spufs_fpcr_fops, 0666, sizeof(struct spu_reg128), },
  2094. { "lslr", &spufs_lslr_ops, 0444, },
  2095. { "mfc", &spufs_mfc_fops, 0666, },
  2096. { "mss", &spufs_mss_fops, 0666, },
  2097. { "npc", &spufs_npc_ops, 0666, },
  2098. { "srr0", &spufs_srr0_ops, 0666, },
  2099. { "decr", &spufs_decr_ops, 0666, },
  2100. { "decr_status", &spufs_decr_status_ops, 0666, },
  2101. { "event_mask", &spufs_event_mask_ops, 0666, },
  2102. { "event_status", &spufs_event_status_ops, 0444, },
  2103. { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, },
  2104. { "phys-id", &spufs_id_ops, 0666, },
  2105. { "object-id", &spufs_object_id_ops, 0666, },
  2106. { "mbox_info", &spufs_mbox_info_fops, 0444, sizeof(u32), },
  2107. { "ibox_info", &spufs_ibox_info_fops, 0444, sizeof(u32), },
  2108. { "wbox_info", &spufs_wbox_info_fops, 0444, sizeof(u32), },
  2109. { "dma_info", &spufs_dma_info_fops, 0444,
  2110. sizeof(struct spu_dma_info), },
  2111. { "proxydma_info", &spufs_proxydma_info_fops, 0444,
  2112. sizeof(struct spu_proxydma_info)},
  2113. { "tid", &spufs_tid_fops, 0444, },
  2114. { "stat", &spufs_stat_fops, 0444, },
  2115. { "switch_log", &spufs_switch_log_fops, 0444 },
  2116. {},
  2117. };
  2118. const struct spufs_tree_descr spufs_dir_nosched_contents[] = {
  2119. { "capabilities", &spufs_caps_fops, 0444, },
  2120. { "mem", &spufs_mem_fops, 0666, LS_SIZE, },
  2121. { "mbox", &spufs_mbox_fops, 0444, },
  2122. { "ibox", &spufs_ibox_fops, 0444, },
  2123. { "wbox", &spufs_wbox_fops, 0222, },
  2124. { "mbox_stat", &spufs_mbox_stat_fops, 0444, sizeof(u32), },
  2125. { "ibox_stat", &spufs_ibox_stat_fops, 0444, sizeof(u32), },
  2126. { "wbox_stat", &spufs_wbox_stat_fops, 0444, sizeof(u32), },
  2127. { "signal1", &spufs_signal1_nosched_fops, 0222, },
  2128. { "signal2", &spufs_signal2_nosched_fops, 0222, },
  2129. { "signal1_type", &spufs_signal1_type, 0666, },
  2130. { "signal2_type", &spufs_signal2_type, 0666, },
  2131. { "mss", &spufs_mss_fops, 0666, },
  2132. { "mfc", &spufs_mfc_fops, 0666, },
  2133. { "cntl", &spufs_cntl_fops, 0666, },
  2134. { "npc", &spufs_npc_ops, 0666, },
  2135. { "psmap", &spufs_psmap_fops, 0666, SPUFS_PS_MAP_SIZE, },
  2136. { "phys-id", &spufs_id_ops, 0666, },
  2137. { "object-id", &spufs_object_id_ops, 0666, },
  2138. { "tid", &spufs_tid_fops, 0444, },
  2139. { "stat", &spufs_stat_fops, 0444, },
  2140. {},
  2141. };
  2142. const struct spufs_tree_descr spufs_dir_debug_contents[] = {
  2143. { ".ctx", &spufs_ctx_fops, 0444, },
  2144. {},
  2145. };
  2146. const struct spufs_coredump_reader spufs_coredump_read[] = {
  2147. { "regs", spufs_regs_dump, NULL, sizeof(struct spu_reg128[128])},
  2148. { "fpcr", spufs_fpcr_dump, NULL, sizeof(struct spu_reg128) },
  2149. { "lslr", NULL, spufs_lslr_get, 19 },
  2150. { "decr", NULL, spufs_decr_get, 19 },
  2151. { "decr_status", NULL, spufs_decr_status_get, 19 },
  2152. { "mem", spufs_mem_dump, NULL, LS_SIZE, },
  2153. { "signal1", spufs_signal1_dump, NULL, sizeof(u32) },
  2154. { "signal1_type", NULL, spufs_signal1_type_get, 19 },
  2155. { "signal2", spufs_signal2_dump, NULL, sizeof(u32) },
  2156. { "signal2_type", NULL, spufs_signal2_type_get, 19 },
  2157. { "event_mask", NULL, spufs_event_mask_get, 19 },
  2158. { "event_status", NULL, spufs_event_status_get, 19 },
  2159. { "mbox_info", spufs_mbox_info_dump, NULL, sizeof(u32) },
  2160. { "ibox_info", spufs_ibox_info_dump, NULL, sizeof(u32) },
  2161. { "wbox_info", spufs_wbox_info_dump, NULL, 4 * sizeof(u32)},
  2162. { "dma_info", spufs_dma_info_dump, NULL, sizeof(struct spu_dma_info)},
  2163. { "proxydma_info", spufs_proxydma_info_dump,
  2164. NULL, sizeof(struct spu_proxydma_info)},
  2165. { "object-id", NULL, spufs_object_id_get, 19 },
  2166. { "npc", NULL, spufs_npc_get, 19 },
  2167. { NULL },
  2168. };