vme_fake.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307
  1. /*
  2. * Fake VME bridge support.
  3. *
  4. * This drive provides a fake VME bridge chip, this enables debugging of the
  5. * VME framework in the absence of a VME system.
  6. *
  7. * This driver has to do a number of things in software that would be driven
  8. * by hardware if it was available, it will also result in extra overhead at
  9. * times when compared with driving actual hardware.
  10. *
  11. * Author: Martyn Welch <martyn@welches.me.uk>
  12. * Copyright (c) 2014 Martyn Welch
  13. *
  14. * Based on vme_tsi148.c:
  15. *
  16. * Author: Martyn Welch <martyn.welch@ge.com>
  17. * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
  18. *
  19. * Based on work by Tom Armistead and Ajit Prem
  20. * Copyright 2004 Motorola Inc.
  21. *
  22. * This program is free software; you can redistribute it and/or modify it
  23. * under the terms of the GNU General Public License as published by the
  24. * Free Software Foundation; either version 2 of the License, or (at your
  25. * option) any later version.
  26. */
  27. #include <linux/device.h>
  28. #include <linux/errno.h>
  29. #include <linux/interrupt.h>
  30. #include <linux/module.h>
  31. #include <linux/moduleparam.h>
  32. #include <linux/slab.h>
  33. #include <linux/spinlock.h>
  34. #include <linux/types.h>
  35. #include <linux/vme.h>
  36. #include "../vme_bridge.h"
  37. /*
  38. * Define the number of each that the fake driver supports.
  39. */
  40. #define FAKE_MAX_MASTER 8 /* Max Master Windows */
  41. #define FAKE_MAX_SLAVE 8 /* Max Slave Windows */
  42. /* Structures to hold information normally held in device registers */
  43. struct fake_slave_window {
  44. int enabled;
  45. unsigned long long vme_base;
  46. unsigned long long size;
  47. void *buf_base;
  48. u32 aspace;
  49. u32 cycle;
  50. };
  51. struct fake_master_window {
  52. int enabled;
  53. unsigned long long vme_base;
  54. unsigned long long size;
  55. u32 aspace;
  56. u32 cycle;
  57. u32 dwidth;
  58. };
  59. /* Structure used to hold driver specific information */
  60. struct fake_driver {
  61. struct vme_bridge *parent;
  62. struct fake_slave_window slaves[FAKE_MAX_SLAVE];
  63. struct fake_master_window masters[FAKE_MAX_MASTER];
  64. u32 lm_enabled;
  65. unsigned long long lm_base;
  66. u32 lm_aspace;
  67. u32 lm_cycle;
  68. void (*lm_callback[4])(void *);
  69. void *lm_data[4];
  70. struct tasklet_struct int_tasklet;
  71. int int_level;
  72. int int_statid;
  73. void *crcsr_kernel;
  74. dma_addr_t crcsr_bus;
  75. /* Only one VME interrupt can be generated at a time, provide locking */
  76. struct mutex vme_int;
  77. };
  78. /* Module parameter */
  79. static int geoid;
  80. static const char driver_name[] = "vme_fake";
  81. static struct vme_bridge *exit_pointer;
  82. static struct device *vme_root;
  83. /*
  84. * Calling VME bus interrupt callback if provided.
  85. */
  86. static void fake_VIRQ_tasklet(unsigned long data)
  87. {
  88. struct vme_bridge *fake_bridge;
  89. struct fake_driver *bridge;
  90. fake_bridge = (struct vme_bridge *) data;
  91. bridge = fake_bridge->driver_priv;
  92. vme_irq_handler(fake_bridge, bridge->int_level, bridge->int_statid);
  93. }
  94. /*
  95. * Configure VME interrupt
  96. */
  97. static void fake_irq_set(struct vme_bridge *fake_bridge, int level,
  98. int state, int sync)
  99. {
  100. /* Nothing to do */
  101. }
  102. static void *fake_pci_to_ptr(dma_addr_t addr)
  103. {
  104. return (void *)(uintptr_t)addr;
  105. }
  106. static dma_addr_t fake_ptr_to_pci(void *addr)
  107. {
  108. return (dma_addr_t)(uintptr_t)addr;
  109. }
  110. /*
  111. * Generate a VME bus interrupt at the requested level & vector. Wait for
  112. * interrupt to be acked.
  113. */
  114. static int fake_irq_generate(struct vme_bridge *fake_bridge, int level,
  115. int statid)
  116. {
  117. struct fake_driver *bridge;
  118. bridge = fake_bridge->driver_priv;
  119. mutex_lock(&bridge->vme_int);
  120. bridge->int_level = level;
  121. bridge->int_statid = statid;
  122. /*
  123. * Schedule tasklet to run VME handler to emulate normal VME interrupt
  124. * handler behaviour.
  125. */
  126. tasklet_schedule(&bridge->int_tasklet);
  127. mutex_unlock(&bridge->vme_int);
  128. return 0;
  129. }
  130. /*
  131. * Initialize a slave window with the requested attributes.
  132. */
  133. static int fake_slave_set(struct vme_slave_resource *image, int enabled,
  134. unsigned long long vme_base, unsigned long long size,
  135. dma_addr_t buf_base, u32 aspace, u32 cycle)
  136. {
  137. unsigned int i, granularity = 0;
  138. unsigned long long vme_bound;
  139. struct vme_bridge *fake_bridge;
  140. struct fake_driver *bridge;
  141. fake_bridge = image->parent;
  142. bridge = fake_bridge->driver_priv;
  143. i = image->number;
  144. switch (aspace) {
  145. case VME_A16:
  146. granularity = 0x10;
  147. break;
  148. case VME_A24:
  149. granularity = 0x1000;
  150. break;
  151. case VME_A32:
  152. granularity = 0x10000;
  153. break;
  154. case VME_A64:
  155. granularity = 0x10000;
  156. break;
  157. case VME_CRCSR:
  158. case VME_USER1:
  159. case VME_USER2:
  160. case VME_USER3:
  161. case VME_USER4:
  162. default:
  163. pr_err("Invalid address space\n");
  164. return -EINVAL;
  165. }
  166. /*
  167. * Bound address is a valid address for the window, adjust
  168. * accordingly
  169. */
  170. vme_bound = vme_base + size - granularity;
  171. if (vme_base & (granularity - 1)) {
  172. pr_err("Invalid VME base alignment\n");
  173. return -EINVAL;
  174. }
  175. if (vme_bound & (granularity - 1)) {
  176. pr_err("Invalid VME bound alignment\n");
  177. return -EINVAL;
  178. }
  179. mutex_lock(&image->mtx);
  180. bridge->slaves[i].enabled = enabled;
  181. bridge->slaves[i].vme_base = vme_base;
  182. bridge->slaves[i].size = size;
  183. bridge->slaves[i].buf_base = fake_pci_to_ptr(buf_base);
  184. bridge->slaves[i].aspace = aspace;
  185. bridge->slaves[i].cycle = cycle;
  186. mutex_unlock(&image->mtx);
  187. return 0;
  188. }
  189. /*
  190. * Get slave window configuration.
  191. */
  192. static int fake_slave_get(struct vme_slave_resource *image, int *enabled,
  193. unsigned long long *vme_base, unsigned long long *size,
  194. dma_addr_t *buf_base, u32 *aspace, u32 *cycle)
  195. {
  196. unsigned int i;
  197. struct fake_driver *bridge;
  198. bridge = image->parent->driver_priv;
  199. i = image->number;
  200. mutex_lock(&image->mtx);
  201. *enabled = bridge->slaves[i].enabled;
  202. *vme_base = bridge->slaves[i].vme_base;
  203. *size = bridge->slaves[i].size;
  204. *buf_base = fake_ptr_to_pci(bridge->slaves[i].buf_base);
  205. *aspace = bridge->slaves[i].aspace;
  206. *cycle = bridge->slaves[i].cycle;
  207. mutex_unlock(&image->mtx);
  208. return 0;
  209. }
  210. /*
  211. * Set the attributes of an outbound window.
  212. */
  213. static int fake_master_set(struct vme_master_resource *image, int enabled,
  214. unsigned long long vme_base, unsigned long long size,
  215. u32 aspace, u32 cycle, u32 dwidth)
  216. {
  217. int retval = 0;
  218. unsigned int i;
  219. struct vme_bridge *fake_bridge;
  220. struct fake_driver *bridge;
  221. fake_bridge = image->parent;
  222. bridge = fake_bridge->driver_priv;
  223. /* Verify input data */
  224. if (vme_base & 0xFFFF) {
  225. pr_err("Invalid VME Window alignment\n");
  226. retval = -EINVAL;
  227. goto err_window;
  228. }
  229. if (size & 0xFFFF) {
  230. pr_err("Invalid size alignment\n");
  231. retval = -EINVAL;
  232. goto err_window;
  233. }
  234. if ((size == 0) && (enabled != 0)) {
  235. pr_err("Size must be non-zero for enabled windows\n");
  236. retval = -EINVAL;
  237. goto err_window;
  238. }
  239. /* Setup data width */
  240. switch (dwidth) {
  241. case VME_D8:
  242. case VME_D16:
  243. case VME_D32:
  244. break;
  245. default:
  246. pr_err("Invalid data width\n");
  247. retval = -EINVAL;
  248. goto err_dwidth;
  249. }
  250. /* Setup address space */
  251. switch (aspace) {
  252. case VME_A16:
  253. case VME_A24:
  254. case VME_A32:
  255. case VME_A64:
  256. case VME_CRCSR:
  257. case VME_USER1:
  258. case VME_USER2:
  259. case VME_USER3:
  260. case VME_USER4:
  261. break;
  262. default:
  263. pr_err("Invalid address space\n");
  264. retval = -EINVAL;
  265. goto err_aspace;
  266. }
  267. spin_lock(&image->lock);
  268. i = image->number;
  269. bridge->masters[i].enabled = enabled;
  270. bridge->masters[i].vme_base = vme_base;
  271. bridge->masters[i].size = size;
  272. bridge->masters[i].aspace = aspace;
  273. bridge->masters[i].cycle = cycle;
  274. bridge->masters[i].dwidth = dwidth;
  275. spin_unlock(&image->lock);
  276. return 0;
  277. err_aspace:
  278. err_dwidth:
  279. err_window:
  280. return retval;
  281. }
  282. /*
  283. * Set the attributes of an outbound window.
  284. */
  285. static int __fake_master_get(struct vme_master_resource *image, int *enabled,
  286. unsigned long long *vme_base, unsigned long long *size,
  287. u32 *aspace, u32 *cycle, u32 *dwidth)
  288. {
  289. unsigned int i;
  290. struct fake_driver *bridge;
  291. bridge = image->parent->driver_priv;
  292. i = image->number;
  293. *enabled = bridge->masters[i].enabled;
  294. *vme_base = bridge->masters[i].vme_base;
  295. *size = bridge->masters[i].size;
  296. *aspace = bridge->masters[i].aspace;
  297. *cycle = bridge->masters[i].cycle;
  298. *dwidth = bridge->masters[i].dwidth;
  299. return 0;
  300. }
  301. static int fake_master_get(struct vme_master_resource *image, int *enabled,
  302. unsigned long long *vme_base, unsigned long long *size,
  303. u32 *aspace, u32 *cycle, u32 *dwidth)
  304. {
  305. int retval;
  306. spin_lock(&image->lock);
  307. retval = __fake_master_get(image, enabled, vme_base, size, aspace,
  308. cycle, dwidth);
  309. spin_unlock(&image->lock);
  310. return retval;
  311. }
  312. static void fake_lm_check(struct fake_driver *bridge, unsigned long long addr,
  313. u32 aspace, u32 cycle)
  314. {
  315. struct vme_bridge *fake_bridge;
  316. unsigned long long lm_base;
  317. u32 lm_aspace, lm_cycle;
  318. int i;
  319. struct vme_lm_resource *lm;
  320. struct list_head *pos = NULL, *n;
  321. /* Get vme_bridge */
  322. fake_bridge = bridge->parent;
  323. /* Loop through each location monitor resource */
  324. list_for_each_safe(pos, n, &fake_bridge->lm_resources) {
  325. lm = list_entry(pos, struct vme_lm_resource, list);
  326. /* If disabled, we're done */
  327. if (bridge->lm_enabled == 0)
  328. return;
  329. lm_base = bridge->lm_base;
  330. lm_aspace = bridge->lm_aspace;
  331. lm_cycle = bridge->lm_cycle;
  332. /* First make sure that the cycle and address space match */
  333. if ((lm_aspace == aspace) && (lm_cycle == cycle)) {
  334. for (i = 0; i < lm->monitors; i++) {
  335. /* Each location monitor covers 8 bytes */
  336. if (((lm_base + (8 * i)) <= addr) &&
  337. ((lm_base + (8 * i) + 8) > addr)) {
  338. if (bridge->lm_callback[i] != NULL)
  339. bridge->lm_callback[i](
  340. bridge->lm_data[i]);
  341. }
  342. }
  343. }
  344. }
  345. }
  346. static u8 fake_vmeread8(struct fake_driver *bridge, unsigned long long addr,
  347. u32 aspace, u32 cycle)
  348. {
  349. u8 retval = 0xff;
  350. int i;
  351. unsigned long long start, end, offset;
  352. u8 *loc;
  353. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  354. start = bridge->slaves[i].vme_base;
  355. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  356. if (aspace != bridge->slaves[i].aspace)
  357. continue;
  358. if (cycle != bridge->slaves[i].cycle)
  359. continue;
  360. if ((addr >= start) && (addr < end)) {
  361. offset = addr - bridge->slaves[i].vme_base;
  362. loc = (u8 *)(bridge->slaves[i].buf_base + offset);
  363. retval = *loc;
  364. break;
  365. }
  366. }
  367. fake_lm_check(bridge, addr, aspace, cycle);
  368. return retval;
  369. }
  370. static u16 fake_vmeread16(struct fake_driver *bridge, unsigned long long addr,
  371. u32 aspace, u32 cycle)
  372. {
  373. u16 retval = 0xffff;
  374. int i;
  375. unsigned long long start, end, offset;
  376. u16 *loc;
  377. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  378. if (aspace != bridge->slaves[i].aspace)
  379. continue;
  380. if (cycle != bridge->slaves[i].cycle)
  381. continue;
  382. start = bridge->slaves[i].vme_base;
  383. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  384. if ((addr >= start) && ((addr + 1) < end)) {
  385. offset = addr - bridge->slaves[i].vme_base;
  386. loc = (u16 *)(bridge->slaves[i].buf_base + offset);
  387. retval = *loc;
  388. break;
  389. }
  390. }
  391. fake_lm_check(bridge, addr, aspace, cycle);
  392. return retval;
  393. }
  394. static u32 fake_vmeread32(struct fake_driver *bridge, unsigned long long addr,
  395. u32 aspace, u32 cycle)
  396. {
  397. u32 retval = 0xffffffff;
  398. int i;
  399. unsigned long long start, end, offset;
  400. u32 *loc;
  401. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  402. if (aspace != bridge->slaves[i].aspace)
  403. continue;
  404. if (cycle != bridge->slaves[i].cycle)
  405. continue;
  406. start = bridge->slaves[i].vme_base;
  407. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  408. if ((addr >= start) && ((addr + 3) < end)) {
  409. offset = addr - bridge->slaves[i].vme_base;
  410. loc = (u32 *)(bridge->slaves[i].buf_base + offset);
  411. retval = *loc;
  412. break;
  413. }
  414. }
  415. fake_lm_check(bridge, addr, aspace, cycle);
  416. return retval;
  417. }
  418. static ssize_t fake_master_read(struct vme_master_resource *image, void *buf,
  419. size_t count, loff_t offset)
  420. {
  421. int retval;
  422. u32 aspace, cycle, dwidth;
  423. struct vme_bridge *fake_bridge;
  424. struct fake_driver *priv;
  425. int i;
  426. unsigned long long addr;
  427. unsigned int done = 0;
  428. unsigned int count32;
  429. fake_bridge = image->parent;
  430. priv = fake_bridge->driver_priv;
  431. i = image->number;
  432. addr = (unsigned long long)priv->masters[i].vme_base + offset;
  433. aspace = priv->masters[i].aspace;
  434. cycle = priv->masters[i].cycle;
  435. dwidth = priv->masters[i].dwidth;
  436. spin_lock(&image->lock);
  437. /* The following code handles VME address alignment. We cannot use
  438. * memcpy_xxx here because it may cut data transfers in to 8-bit
  439. * cycles when D16 or D32 cycles are required on the VME bus.
  440. * On the other hand, the bridge itself assures that the maximum data
  441. * cycle configured for the transfer is used and splits it
  442. * automatically for non-aligned addresses, so we don't want the
  443. * overhead of needlessly forcing small transfers for the entire cycle.
  444. */
  445. if (addr & 0x1) {
  446. *(u8 *)buf = fake_vmeread8(priv, addr, aspace, cycle);
  447. done += 1;
  448. if (done == count)
  449. goto out;
  450. }
  451. if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
  452. if ((addr + done) & 0x2) {
  453. if ((count - done) < 2) {
  454. *(u8 *)(buf + done) = fake_vmeread8(priv,
  455. addr + done, aspace, cycle);
  456. done += 1;
  457. goto out;
  458. } else {
  459. *(u16 *)(buf + done) = fake_vmeread16(priv,
  460. addr + done, aspace, cycle);
  461. done += 2;
  462. }
  463. }
  464. }
  465. if (dwidth == VME_D32) {
  466. count32 = (count - done) & ~0x3;
  467. while (done < count32) {
  468. *(u32 *)(buf + done) = fake_vmeread32(priv, addr + done,
  469. aspace, cycle);
  470. done += 4;
  471. }
  472. } else if (dwidth == VME_D16) {
  473. count32 = (count - done) & ~0x3;
  474. while (done < count32) {
  475. *(u16 *)(buf + done) = fake_vmeread16(priv, addr + done,
  476. aspace, cycle);
  477. done += 2;
  478. }
  479. } else if (dwidth == VME_D8) {
  480. count32 = (count - done);
  481. while (done < count32) {
  482. *(u8 *)(buf + done) = fake_vmeread8(priv, addr + done,
  483. aspace, cycle);
  484. done += 1;
  485. }
  486. }
  487. if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
  488. if ((count - done) & 0x2) {
  489. *(u16 *)(buf + done) = fake_vmeread16(priv, addr + done,
  490. aspace, cycle);
  491. done += 2;
  492. }
  493. }
  494. if ((count - done) & 0x1) {
  495. *(u8 *)(buf + done) = fake_vmeread8(priv, addr + done, aspace,
  496. cycle);
  497. done += 1;
  498. }
  499. out:
  500. retval = count;
  501. spin_unlock(&image->lock);
  502. return retval;
  503. }
  504. static void fake_vmewrite8(struct fake_driver *bridge, u8 *buf,
  505. unsigned long long addr, u32 aspace, u32 cycle)
  506. {
  507. int i;
  508. unsigned long long start, end, offset;
  509. u8 *loc;
  510. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  511. if (aspace != bridge->slaves[i].aspace)
  512. continue;
  513. if (cycle != bridge->slaves[i].cycle)
  514. continue;
  515. start = bridge->slaves[i].vme_base;
  516. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  517. if ((addr >= start) && (addr < end)) {
  518. offset = addr - bridge->slaves[i].vme_base;
  519. loc = (u8 *)((void *)bridge->slaves[i].buf_base + offset);
  520. *loc = *buf;
  521. break;
  522. }
  523. }
  524. fake_lm_check(bridge, addr, aspace, cycle);
  525. }
  526. static void fake_vmewrite16(struct fake_driver *bridge, u16 *buf,
  527. unsigned long long addr, u32 aspace, u32 cycle)
  528. {
  529. int i;
  530. unsigned long long start, end, offset;
  531. u16 *loc;
  532. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  533. if (aspace != bridge->slaves[i].aspace)
  534. continue;
  535. if (cycle != bridge->slaves[i].cycle)
  536. continue;
  537. start = bridge->slaves[i].vme_base;
  538. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  539. if ((addr >= start) && ((addr + 1) < end)) {
  540. offset = addr - bridge->slaves[i].vme_base;
  541. loc = (u16 *)((void *)bridge->slaves[i].buf_base + offset);
  542. *loc = *buf;
  543. break;
  544. }
  545. }
  546. fake_lm_check(bridge, addr, aspace, cycle);
  547. }
  548. static void fake_vmewrite32(struct fake_driver *bridge, u32 *buf,
  549. unsigned long long addr, u32 aspace, u32 cycle)
  550. {
  551. int i;
  552. unsigned long long start, end, offset;
  553. u32 *loc;
  554. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  555. if (aspace != bridge->slaves[i].aspace)
  556. continue;
  557. if (cycle != bridge->slaves[i].cycle)
  558. continue;
  559. start = bridge->slaves[i].vme_base;
  560. end = bridge->slaves[i].vme_base + bridge->slaves[i].size;
  561. if ((addr >= start) && ((addr + 3) < end)) {
  562. offset = addr - bridge->slaves[i].vme_base;
  563. loc = (u32 *)((void *)bridge->slaves[i].buf_base + offset);
  564. *loc = *buf;
  565. break;
  566. }
  567. }
  568. fake_lm_check(bridge, addr, aspace, cycle);
  569. }
  570. static ssize_t fake_master_write(struct vme_master_resource *image, void *buf,
  571. size_t count, loff_t offset)
  572. {
  573. int retval = 0;
  574. u32 aspace, cycle, dwidth;
  575. unsigned long long addr;
  576. int i;
  577. unsigned int done = 0;
  578. unsigned int count32;
  579. struct vme_bridge *fake_bridge;
  580. struct fake_driver *bridge;
  581. fake_bridge = image->parent;
  582. bridge = fake_bridge->driver_priv;
  583. i = image->number;
  584. addr = bridge->masters[i].vme_base + offset;
  585. aspace = bridge->masters[i].aspace;
  586. cycle = bridge->masters[i].cycle;
  587. dwidth = bridge->masters[i].dwidth;
  588. spin_lock(&image->lock);
  589. /* Here we apply for the same strategy we do in master_read
  590. * function in order to assure the correct cycles.
  591. */
  592. if (addr & 0x1) {
  593. fake_vmewrite8(bridge, (u8 *)buf, addr, aspace, cycle);
  594. done += 1;
  595. if (done == count)
  596. goto out;
  597. }
  598. if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
  599. if ((addr + done) & 0x2) {
  600. if ((count - done) < 2) {
  601. fake_vmewrite8(bridge, (u8 *)(buf + done),
  602. addr + done, aspace, cycle);
  603. done += 1;
  604. goto out;
  605. } else {
  606. fake_vmewrite16(bridge, (u16 *)(buf + done),
  607. addr + done, aspace, cycle);
  608. done += 2;
  609. }
  610. }
  611. }
  612. if (dwidth == VME_D32) {
  613. count32 = (count - done) & ~0x3;
  614. while (done < count32) {
  615. fake_vmewrite32(bridge, (u32 *)(buf + done),
  616. addr + done, aspace, cycle);
  617. done += 4;
  618. }
  619. } else if (dwidth == VME_D16) {
  620. count32 = (count - done) & ~0x3;
  621. while (done < count32) {
  622. fake_vmewrite16(bridge, (u16 *)(buf + done),
  623. addr + done, aspace, cycle);
  624. done += 2;
  625. }
  626. } else if (dwidth == VME_D8) {
  627. count32 = (count - done);
  628. while (done < count32) {
  629. fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done,
  630. aspace, cycle);
  631. done += 1;
  632. }
  633. }
  634. if ((dwidth == VME_D16) || (dwidth == VME_D32)) {
  635. if ((count - done) & 0x2) {
  636. fake_vmewrite16(bridge, (u16 *)(buf + done),
  637. addr + done, aspace, cycle);
  638. done += 2;
  639. }
  640. }
  641. if ((count - done) & 0x1) {
  642. fake_vmewrite8(bridge, (u8 *)(buf + done), addr + done, aspace,
  643. cycle);
  644. done += 1;
  645. }
  646. out:
  647. retval = count;
  648. spin_unlock(&image->lock);
  649. return retval;
  650. }
  651. /*
  652. * Perform an RMW cycle on the VME bus.
  653. *
  654. * Requires a previously configured master window, returns final value.
  655. */
  656. static unsigned int fake_master_rmw(struct vme_master_resource *image,
  657. unsigned int mask, unsigned int compare, unsigned int swap,
  658. loff_t offset)
  659. {
  660. u32 tmp, base;
  661. u32 aspace, cycle;
  662. int i;
  663. struct fake_driver *bridge;
  664. bridge = image->parent->driver_priv;
  665. /* Find the PCI address that maps to the desired VME address */
  666. i = image->number;
  667. base = bridge->masters[i].vme_base;
  668. aspace = bridge->masters[i].aspace;
  669. cycle = bridge->masters[i].cycle;
  670. /* Lock image */
  671. spin_lock(&image->lock);
  672. /* Read existing value */
  673. tmp = fake_vmeread32(bridge, base + offset, aspace, cycle);
  674. /* Perform check */
  675. if ((tmp && mask) == (compare && mask)) {
  676. tmp = tmp | (mask | swap);
  677. tmp = tmp & (~mask | swap);
  678. /* Write back */
  679. fake_vmewrite32(bridge, &tmp, base + offset, aspace, cycle);
  680. }
  681. /* Unlock image */
  682. spin_unlock(&image->lock);
  683. return tmp;
  684. }
  685. /*
  686. * All 4 location monitors reside at the same base - this is therefore a
  687. * system wide configuration.
  688. *
  689. * This does not enable the LM monitor - that should be done when the first
  690. * callback is attached and disabled when the last callback is removed.
  691. */
  692. static int fake_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
  693. u32 aspace, u32 cycle)
  694. {
  695. int i;
  696. struct vme_bridge *fake_bridge;
  697. struct fake_driver *bridge;
  698. fake_bridge = lm->parent;
  699. bridge = fake_bridge->driver_priv;
  700. mutex_lock(&lm->mtx);
  701. /* If we already have a callback attached, we can't move it! */
  702. for (i = 0; i < lm->monitors; i++) {
  703. if (bridge->lm_callback[i] != NULL) {
  704. mutex_unlock(&lm->mtx);
  705. pr_err("Location monitor callback attached, can't reset\n");
  706. return -EBUSY;
  707. }
  708. }
  709. switch (aspace) {
  710. case VME_A16:
  711. case VME_A24:
  712. case VME_A32:
  713. case VME_A64:
  714. break;
  715. default:
  716. mutex_unlock(&lm->mtx);
  717. pr_err("Invalid address space\n");
  718. return -EINVAL;
  719. }
  720. bridge->lm_base = lm_base;
  721. bridge->lm_aspace = aspace;
  722. bridge->lm_cycle = cycle;
  723. mutex_unlock(&lm->mtx);
  724. return 0;
  725. }
  726. /* Get configuration of the callback monitor and return whether it is enabled
  727. * or disabled.
  728. */
  729. static int fake_lm_get(struct vme_lm_resource *lm,
  730. unsigned long long *lm_base, u32 *aspace, u32 *cycle)
  731. {
  732. struct fake_driver *bridge;
  733. bridge = lm->parent->driver_priv;
  734. mutex_lock(&lm->mtx);
  735. *lm_base = bridge->lm_base;
  736. *aspace = bridge->lm_aspace;
  737. *cycle = bridge->lm_cycle;
  738. mutex_unlock(&lm->mtx);
  739. return bridge->lm_enabled;
  740. }
  741. /*
  742. * Attach a callback to a specific location monitor.
  743. *
  744. * Callback will be passed the monitor triggered.
  745. */
  746. static int fake_lm_attach(struct vme_lm_resource *lm, int monitor,
  747. void (*callback)(void *), void *data)
  748. {
  749. struct vme_bridge *fake_bridge;
  750. struct fake_driver *bridge;
  751. fake_bridge = lm->parent;
  752. bridge = fake_bridge->driver_priv;
  753. mutex_lock(&lm->mtx);
  754. /* Ensure that the location monitor is configured - need PGM or DATA */
  755. if (bridge->lm_cycle == 0) {
  756. mutex_unlock(&lm->mtx);
  757. pr_err("Location monitor not properly configured\n");
  758. return -EINVAL;
  759. }
  760. /* Check that a callback isn't already attached */
  761. if (bridge->lm_callback[monitor] != NULL) {
  762. mutex_unlock(&lm->mtx);
  763. pr_err("Existing callback attached\n");
  764. return -EBUSY;
  765. }
  766. /* Attach callback */
  767. bridge->lm_callback[monitor] = callback;
  768. bridge->lm_data[monitor] = data;
  769. /* Ensure that global Location Monitor Enable set */
  770. bridge->lm_enabled = 1;
  771. mutex_unlock(&lm->mtx);
  772. return 0;
  773. }
  774. /*
  775. * Detach a callback function forn a specific location monitor.
  776. */
  777. static int fake_lm_detach(struct vme_lm_resource *lm, int monitor)
  778. {
  779. u32 tmp;
  780. int i;
  781. struct fake_driver *bridge;
  782. bridge = lm->parent->driver_priv;
  783. mutex_lock(&lm->mtx);
  784. /* Detach callback */
  785. bridge->lm_callback[monitor] = NULL;
  786. bridge->lm_data[monitor] = NULL;
  787. /* If all location monitors disabled, disable global Location Monitor */
  788. tmp = 0;
  789. for (i = 0; i < lm->monitors; i++) {
  790. if (bridge->lm_callback[i] != NULL)
  791. tmp = 1;
  792. }
  793. if (tmp == 0)
  794. bridge->lm_enabled = 0;
  795. mutex_unlock(&lm->mtx);
  796. return 0;
  797. }
  798. /*
  799. * Determine Geographical Addressing
  800. */
  801. static int fake_slot_get(struct vme_bridge *fake_bridge)
  802. {
  803. return geoid;
  804. }
  805. static void *fake_alloc_consistent(struct device *parent, size_t size,
  806. dma_addr_t *dma)
  807. {
  808. void *alloc = kmalloc(size, GFP_KERNEL);
  809. if (alloc != NULL)
  810. *dma = fake_ptr_to_pci(alloc);
  811. return alloc;
  812. }
  813. static void fake_free_consistent(struct device *parent, size_t size,
  814. void *vaddr, dma_addr_t dma)
  815. {
  816. kfree(vaddr);
  817. /*
  818. dma_free_coherent(parent, size, vaddr, dma);
  819. */
  820. }
  821. /*
  822. * Configure CR/CSR space
  823. *
  824. * Access to the CR/CSR can be configured at power-up. The location of the
  825. * CR/CSR registers in the CR/CSR address space is determined by the boards
  826. * Geographic address.
  827. *
  828. * Each board has a 512kB window, with the highest 4kB being used for the
  829. * boards registers, this means there is a fix length 508kB window which must
  830. * be mapped onto PCI memory.
  831. */
  832. static int fake_crcsr_init(struct vme_bridge *fake_bridge)
  833. {
  834. u32 vstat;
  835. struct fake_driver *bridge;
  836. bridge = fake_bridge->driver_priv;
  837. /* Allocate mem for CR/CSR image */
  838. bridge->crcsr_kernel = kzalloc(VME_CRCSR_BUF_SIZE, GFP_KERNEL);
  839. bridge->crcsr_bus = fake_ptr_to_pci(bridge->crcsr_kernel);
  840. if (bridge->crcsr_kernel == NULL)
  841. return -ENOMEM;
  842. vstat = fake_slot_get(fake_bridge);
  843. pr_info("CR/CSR Offset: %d\n", vstat);
  844. return 0;
  845. }
  846. static void fake_crcsr_exit(struct vme_bridge *fake_bridge)
  847. {
  848. struct fake_driver *bridge;
  849. bridge = fake_bridge->driver_priv;
  850. kfree(bridge->crcsr_kernel);
  851. }
  852. static int __init fake_init(void)
  853. {
  854. int retval, i;
  855. struct list_head *pos = NULL, *n;
  856. struct vme_bridge *fake_bridge;
  857. struct fake_driver *fake_device;
  858. struct vme_master_resource *master_image;
  859. struct vme_slave_resource *slave_image;
  860. struct vme_lm_resource *lm;
  861. /* We need a fake parent device */
  862. vme_root = __root_device_register("vme", THIS_MODULE);
  863. /* If we want to support more than one bridge at some point, we need to
  864. * dynamically allocate this so we get one per device.
  865. */
  866. fake_bridge = kzalloc(sizeof(struct vme_bridge), GFP_KERNEL);
  867. if (fake_bridge == NULL) {
  868. retval = -ENOMEM;
  869. goto err_struct;
  870. }
  871. fake_device = kzalloc(sizeof(struct fake_driver), GFP_KERNEL);
  872. if (fake_device == NULL) {
  873. retval = -ENOMEM;
  874. goto err_driver;
  875. }
  876. fake_bridge->driver_priv = fake_device;
  877. fake_bridge->parent = vme_root;
  878. fake_device->parent = fake_bridge;
  879. /* Initialize wait queues & mutual exclusion flags */
  880. mutex_init(&fake_device->vme_int);
  881. mutex_init(&fake_bridge->irq_mtx);
  882. tasklet_init(&fake_device->int_tasklet, fake_VIRQ_tasklet,
  883. (unsigned long) fake_bridge);
  884. strcpy(fake_bridge->name, driver_name);
  885. /* Add master windows to list */
  886. INIT_LIST_HEAD(&fake_bridge->master_resources);
  887. for (i = 0; i < FAKE_MAX_MASTER; i++) {
  888. master_image = kmalloc(sizeof(struct vme_master_resource),
  889. GFP_KERNEL);
  890. if (master_image == NULL) {
  891. retval = -ENOMEM;
  892. goto err_master;
  893. }
  894. master_image->parent = fake_bridge;
  895. spin_lock_init(&master_image->lock);
  896. master_image->locked = 0;
  897. master_image->number = i;
  898. master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
  899. VME_A64;
  900. master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
  901. VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
  902. VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
  903. VME_PROG | VME_DATA;
  904. master_image->width_attr = VME_D16 | VME_D32;
  905. memset(&master_image->bus_resource, 0,
  906. sizeof(struct resource));
  907. master_image->kern_base = NULL;
  908. list_add_tail(&master_image->list,
  909. &fake_bridge->master_resources);
  910. }
  911. /* Add slave windows to list */
  912. INIT_LIST_HEAD(&fake_bridge->slave_resources);
  913. for (i = 0; i < FAKE_MAX_SLAVE; i++) {
  914. slave_image = kmalloc(sizeof(struct vme_slave_resource),
  915. GFP_KERNEL);
  916. if (slave_image == NULL) {
  917. retval = -ENOMEM;
  918. goto err_slave;
  919. }
  920. slave_image->parent = fake_bridge;
  921. mutex_init(&slave_image->mtx);
  922. slave_image->locked = 0;
  923. slave_image->number = i;
  924. slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
  925. VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
  926. VME_USER3 | VME_USER4;
  927. slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
  928. VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
  929. VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
  930. VME_PROG | VME_DATA;
  931. list_add_tail(&slave_image->list,
  932. &fake_bridge->slave_resources);
  933. }
  934. /* Add location monitor to list */
  935. INIT_LIST_HEAD(&fake_bridge->lm_resources);
  936. lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
  937. if (lm == NULL) {
  938. pr_err("Failed to allocate memory for location monitor resource structure\n");
  939. retval = -ENOMEM;
  940. goto err_lm;
  941. }
  942. lm->parent = fake_bridge;
  943. mutex_init(&lm->mtx);
  944. lm->locked = 0;
  945. lm->number = 1;
  946. lm->monitors = 4;
  947. list_add_tail(&lm->list, &fake_bridge->lm_resources);
  948. fake_bridge->slave_get = fake_slave_get;
  949. fake_bridge->slave_set = fake_slave_set;
  950. fake_bridge->master_get = fake_master_get;
  951. fake_bridge->master_set = fake_master_set;
  952. fake_bridge->master_read = fake_master_read;
  953. fake_bridge->master_write = fake_master_write;
  954. fake_bridge->master_rmw = fake_master_rmw;
  955. fake_bridge->irq_set = fake_irq_set;
  956. fake_bridge->irq_generate = fake_irq_generate;
  957. fake_bridge->lm_set = fake_lm_set;
  958. fake_bridge->lm_get = fake_lm_get;
  959. fake_bridge->lm_attach = fake_lm_attach;
  960. fake_bridge->lm_detach = fake_lm_detach;
  961. fake_bridge->slot_get = fake_slot_get;
  962. fake_bridge->alloc_consistent = fake_alloc_consistent;
  963. fake_bridge->free_consistent = fake_free_consistent;
  964. pr_info("Board is%s the VME system controller\n",
  965. (geoid == 1) ? "" : " not");
  966. pr_info("VME geographical address is set to %d\n", geoid);
  967. retval = fake_crcsr_init(fake_bridge);
  968. if (retval) {
  969. pr_err("CR/CSR configuration failed.\n");
  970. goto err_crcsr;
  971. }
  972. retval = vme_register_bridge(fake_bridge);
  973. if (retval != 0) {
  974. pr_err("Chip Registration failed.\n");
  975. goto err_reg;
  976. }
  977. exit_pointer = fake_bridge;
  978. return 0;
  979. err_reg:
  980. fake_crcsr_exit(fake_bridge);
  981. err_crcsr:
  982. err_lm:
  983. /* resources are stored in link list */
  984. list_for_each_safe(pos, n, &fake_bridge->lm_resources) {
  985. lm = list_entry(pos, struct vme_lm_resource, list);
  986. list_del(pos);
  987. kfree(lm);
  988. }
  989. err_slave:
  990. /* resources are stored in link list */
  991. list_for_each_safe(pos, n, &fake_bridge->slave_resources) {
  992. slave_image = list_entry(pos, struct vme_slave_resource, list);
  993. list_del(pos);
  994. kfree(slave_image);
  995. }
  996. err_master:
  997. /* resources are stored in link list */
  998. list_for_each_safe(pos, n, &fake_bridge->master_resources) {
  999. master_image = list_entry(pos, struct vme_master_resource,
  1000. list);
  1001. list_del(pos);
  1002. kfree(master_image);
  1003. }
  1004. kfree(fake_device);
  1005. err_driver:
  1006. kfree(fake_bridge);
  1007. err_struct:
  1008. return retval;
  1009. }
  1010. static void __exit fake_exit(void)
  1011. {
  1012. struct list_head *pos = NULL;
  1013. struct list_head *tmplist;
  1014. struct vme_master_resource *master_image;
  1015. struct vme_slave_resource *slave_image;
  1016. int i;
  1017. struct vme_bridge *fake_bridge;
  1018. struct fake_driver *bridge;
  1019. fake_bridge = exit_pointer;
  1020. bridge = fake_bridge->driver_priv;
  1021. pr_debug("Driver is being unloaded.\n");
  1022. /*
  1023. * Shutdown all inbound and outbound windows.
  1024. */
  1025. for (i = 0; i < FAKE_MAX_MASTER; i++)
  1026. bridge->masters[i].enabled = 0;
  1027. for (i = 0; i < FAKE_MAX_SLAVE; i++)
  1028. bridge->slaves[i].enabled = 0;
  1029. /*
  1030. * Shutdown Location monitor.
  1031. */
  1032. bridge->lm_enabled = 0;
  1033. vme_unregister_bridge(fake_bridge);
  1034. fake_crcsr_exit(fake_bridge);
  1035. /* resources are stored in link list */
  1036. list_for_each_safe(pos, tmplist, &fake_bridge->slave_resources) {
  1037. slave_image = list_entry(pos, struct vme_slave_resource, list);
  1038. list_del(pos);
  1039. kfree(slave_image);
  1040. }
  1041. /* resources are stored in link list */
  1042. list_for_each_safe(pos, tmplist, &fake_bridge->master_resources) {
  1043. master_image = list_entry(pos, struct vme_master_resource,
  1044. list);
  1045. list_del(pos);
  1046. kfree(master_image);
  1047. }
  1048. kfree(fake_bridge->driver_priv);
  1049. kfree(fake_bridge);
  1050. root_device_unregister(vme_root);
  1051. }
  1052. MODULE_PARM_DESC(geoid, "Set geographical addressing");
  1053. module_param(geoid, int, 0);
  1054. MODULE_DESCRIPTION("Fake VME bridge driver");
  1055. MODULE_LICENSE("GPL");
  1056. module_init(fake_init);
  1057. module_exit(fake_exit);