lamebus.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /*
  30. * Machine-independent LAMEbus code.
  31. */
  32. #include <types.h>
  33. #include <lib.h>
  34. #include <cpu.h>
  35. #include <spinlock.h>
  36. #include <current.h>
  37. #include <lamebus/lamebus.h>
  38. /* Register offsets within each config region */
  39. #define CFGREG_VID 0 /* Vendor ID */
  40. #define CFGREG_DID 4 /* Device ID */
  41. #define CFGREG_DRL 8 /* Device Revision Level */
  42. /* LAMEbus controller private registers (offsets within its config region) */
  43. #define CTLREG_RAMSZ 0x200
  44. #define CTLREG_IRQS 0x204
  45. #define CTLREG_PWR 0x208
  46. #define CTLREG_IRQE 0x20c
  47. #define CTLREG_CPUS 0x210
  48. #define CTLREG_CPUE 0x214
  49. #define CTLREG_SELF 0x218
  50. /* LAMEbus CPU control registers (offsets within each per-cpu region) */
  51. #define CTLCPU_CIRQE 0x000
  52. #define CTLCPU_CIPI 0x004
  53. #define CTLCPU_CRAM 0x300
  54. /*
  55. * Read a config register for the given slot.
  56. */
  57. static
  58. inline
  59. uint32_t
  60. read_cfg_register(struct lamebus_softc *lb, int slot, uint32_t offset)
  61. {
  62. /* Note that lb might be NULL on some platforms in some contexts. */
  63. offset += LB_CONFIG_SIZE*slot;
  64. return lamebus_read_register(lb, LB_CONTROLLER_SLOT, offset);
  65. }
  66. /*
  67. * Write a config register for a given slot.
  68. */
  69. static
  70. inline
  71. void
  72. write_cfg_register(struct lamebus_softc *lb, int slot, uint32_t offset,
  73. uint32_t val)
  74. {
  75. offset += LB_CONFIG_SIZE*slot;
  76. lamebus_write_register(lb, LB_CONTROLLER_SLOT, offset, val);
  77. }
  78. /*
  79. * Read one of the bus controller's registers.
  80. */
  81. static
  82. inline
  83. uint32_t
  84. read_ctl_register(struct lamebus_softc *lb, uint32_t offset)
  85. {
  86. /* Note that lb might be NULL on some platforms in some contexts. */
  87. return read_cfg_register(lb, LB_CONTROLLER_SLOT, offset);
  88. }
  89. /*
  90. * Write one of the bus controller's registers.
  91. */
  92. static
  93. inline
  94. void
  95. write_ctl_register(struct lamebus_softc *lb, uint32_t offset, uint32_t val)
  96. {
  97. write_cfg_register(lb, LB_CONTROLLER_SLOT, offset, val);
  98. }
  99. /*
  100. * Write one of the bus controller's CPU control registers.
  101. */
  102. static
  103. inline
  104. void
  105. write_ctlcpu_register(struct lamebus_softc *lb, unsigned hw_cpunum,
  106. uint32_t offset, uint32_t val)
  107. {
  108. offset += LB_CTLCPU_OFFSET + hw_cpunum * LB_CTLCPU_SIZE;
  109. lamebus_write_register(lb, LB_CONTROLLER_SLOT, offset, val);
  110. }
  111. /*
  112. * Find and create secondary CPUs.
  113. */
  114. void
  115. lamebus_find_cpus(struct lamebus_softc *lamebus)
  116. {
  117. uint32_t cpumask, self, bit, val;
  118. unsigned i, numcpus, bootcpu;
  119. unsigned hwnum[32];
  120. cpumask = read_ctl_register(lamebus, CTLREG_CPUS);
  121. self = read_ctl_register(lamebus, CTLREG_SELF);
  122. numcpus = 0;
  123. bootcpu = 0;
  124. for (i=0; i<32; i++) {
  125. bit = (uint32_t)1 << i;
  126. if ((cpumask & bit) != 0) {
  127. if (self & bit) {
  128. bootcpu = numcpus;
  129. curcpu->c_hardware_number = i;
  130. }
  131. hwnum[numcpus] = i;
  132. numcpus++;
  133. }
  134. }
  135. for (i=0; i<numcpus; i++) {
  136. if (i != bootcpu) {
  137. cpu_create(hwnum[i]);
  138. }
  139. }
  140. /*
  141. * By default, route all interrupts only to the boot cpu. We
  142. * could be arbitrarily more elaborate, up to things like
  143. * dynamic load balancing.
  144. */
  145. for (i=0; i<numcpus; i++) {
  146. if (i != bootcpu) {
  147. val = 0;
  148. }
  149. else {
  150. val = 0xffffffff;
  151. }
  152. write_ctlcpu_register(lamebus, hwnum[i], CTLCPU_CIRQE, val);
  153. }
  154. }
  155. /*
  156. * Start up secondary CPUs.
  157. *
  158. * The first word of the CRAM area is set to the entry point for new
  159. * CPUs; the second to the (software) CPU number. Note that the logic
  160. * here assumes the boot CPU is CPU 0 and the others are 1-N as
  161. * created in the function above. This is fine if all CPUs are on
  162. * LAMEbus; if in some environment there are other CPUs about as well
  163. * this logic will have to be made more complex.
  164. */
  165. void
  166. lamebus_start_cpus(struct lamebus_softc *lamebus)
  167. {
  168. uint32_t cpumask, self, bit;
  169. uint32_t ctlcpuoffset;
  170. uint32_t *cram;
  171. unsigned i;
  172. unsigned cpunum;
  173. cpumask = read_ctl_register(lamebus, CTLREG_CPUS);
  174. self = read_ctl_register(lamebus, CTLREG_SELF);
  175. /* Poke in the startup address. */
  176. cpunum = 1;
  177. for (i=0; i<32; i++) {
  178. bit = (uint32_t)1 << i;
  179. if ((cpumask & bit) != 0) {
  180. if (self & bit) {
  181. continue;
  182. }
  183. ctlcpuoffset = LB_CTLCPU_OFFSET + i * LB_CTLCPU_SIZE;
  184. cram = lamebus_map_area(lamebus,
  185. LB_CONTROLLER_SLOT,
  186. ctlcpuoffset + CTLCPU_CRAM);
  187. cram[0] = (uint32_t)cpu_start_secondary;
  188. cram[1] = cpunum++;
  189. }
  190. }
  191. /* Now, enable them all. */
  192. write_ctl_register(lamebus, CTLREG_CPUE, cpumask);
  193. }
  194. /*
  195. * Probe function.
  196. *
  197. * Given a LAMEbus, look for a device that's not already been marked
  198. * in use, has the specified IDs, and has a device revision level in
  199. * the specified range (which is inclusive on both ends.)
  200. *
  201. * Returns the slot number found (0-31) or -1 if nothing suitable was
  202. * found.
  203. */
  204. int
  205. lamebus_probe(struct lamebus_softc *sc,
  206. uint32_t vendorid, uint32_t deviceid,
  207. uint32_t lowver, uint32_t highver)
  208. {
  209. int slot;
  210. uint32_t val;
  211. /*
  212. * Because the slot information in sc is used when dispatching
  213. * interrupts, disable interrupts while working with it.
  214. */
  215. spinlock_acquire(&sc->ls_lock);
  216. for (slot=0; slot<LB_NSLOTS; slot++) {
  217. if (sc->ls_slotsinuse & (1<<slot)) {
  218. /* Slot already in use; skip */
  219. continue;
  220. }
  221. val = read_cfg_register(sc, slot, CFGREG_VID);
  222. if (val!=vendorid) {
  223. /* Wrong vendor id */
  224. continue;
  225. }
  226. val = read_cfg_register(sc, slot, CFGREG_DID);
  227. if (val != deviceid) {
  228. /* Wrong device id */
  229. continue;
  230. }
  231. val = read_cfg_register(sc, slot, CFGREG_DRL);
  232. if (val < lowver || val > highver) {
  233. /* Unsupported device revision */
  234. continue;
  235. }
  236. /* Found something */
  237. spinlock_release(&sc->ls_lock);
  238. return slot;
  239. }
  240. /* Found nothing */
  241. spinlock_release(&sc->ls_lock);
  242. return -1;
  243. }
  244. /*
  245. * Mark that a slot is in use.
  246. * This prevents the probe routine from returning the same device over
  247. * and over again.
  248. */
  249. void
  250. lamebus_mark(struct lamebus_softc *sc, int slot)
  251. {
  252. uint32_t mask = ((uint32_t)1) << slot;
  253. KASSERT(slot>=0 && slot < LB_NSLOTS);
  254. spinlock_acquire(&sc->ls_lock);
  255. if ((sc->ls_slotsinuse & mask)!=0) {
  256. panic("lamebus_mark: slot %d already in use\n", slot);
  257. }
  258. sc->ls_slotsinuse |= mask;
  259. spinlock_release(&sc->ls_lock);
  260. }
  261. /*
  262. * Mark that a slot is no longer in use.
  263. */
  264. void
  265. lamebus_unmark(struct lamebus_softc *sc, int slot)
  266. {
  267. uint32_t mask = ((uint32_t)1) << slot;
  268. KASSERT(slot>=0 && slot < LB_NSLOTS);
  269. spinlock_acquire(&sc->ls_lock);
  270. if ((sc->ls_slotsinuse & mask)==0) {
  271. panic("lamebus_mark: slot %d not marked in use\n", slot);
  272. }
  273. sc->ls_slotsinuse &= ~mask;
  274. spinlock_release(&sc->ls_lock);
  275. }
  276. /*
  277. * Register a function (and a device context pointer) to be called
  278. * when a particular slot signals an interrupt.
  279. */
  280. void
  281. lamebus_attach_interrupt(struct lamebus_softc *sc, int slot,
  282. void *devdata,
  283. void (*irqfunc)(void *devdata))
  284. {
  285. uint32_t mask = ((uint32_t)1) << slot;
  286. KASSERT(slot>=0 && slot < LB_NSLOTS);
  287. spinlock_acquire(&sc->ls_lock);
  288. if ((sc->ls_slotsinuse & mask)==0) {
  289. panic("lamebus_attach_interrupt: slot %d not marked in use\n",
  290. slot);
  291. }
  292. KASSERT(sc->ls_devdata[slot]==NULL);
  293. KASSERT(sc->ls_irqfuncs[slot]==NULL);
  294. sc->ls_devdata[slot] = devdata;
  295. sc->ls_irqfuncs[slot] = irqfunc;
  296. spinlock_release(&sc->ls_lock);
  297. }
  298. /*
  299. * Unregister a function that was being called when a particular slot
  300. * signaled an interrupt.
  301. */
  302. void
  303. lamebus_detach_interrupt(struct lamebus_softc *sc, int slot)
  304. {
  305. uint32_t mask = ((uint32_t)1) << slot;
  306. KASSERT(slot>=0 && slot < LB_NSLOTS);
  307. spinlock_acquire(&sc->ls_lock);
  308. if ((sc->ls_slotsinuse & mask)==0) {
  309. panic("lamebus_detach_interrupt: slot %d not marked in use\n",
  310. slot);
  311. }
  312. KASSERT(sc->ls_irqfuncs[slot]!=NULL);
  313. sc->ls_devdata[slot] = NULL;
  314. sc->ls_irqfuncs[slot] = NULL;
  315. spinlock_release(&sc->ls_lock);
  316. }
  317. /*
  318. * Mask/unmask an interrupt using the global IRQE register.
  319. */
  320. void
  321. lamebus_mask_interrupt(struct lamebus_softc *lamebus, int slot)
  322. {
  323. uint32_t bits, mask = ((uint32_t)1) << slot;
  324. KASSERT(slot >= 0 && slot < LB_NSLOTS);
  325. spinlock_acquire(&lamebus->ls_lock);
  326. bits = read_ctl_register(lamebus, CTLREG_IRQE);
  327. bits &= ~mask;
  328. write_ctl_register(lamebus, CTLREG_IRQE, bits);
  329. spinlock_release(&lamebus->ls_lock);
  330. }
  331. void
  332. lamebus_unmask_interrupt(struct lamebus_softc *lamebus, int slot)
  333. {
  334. uint32_t bits, mask = ((uint32_t)1) << slot;
  335. KASSERT(slot >= 0 && slot < LB_NSLOTS);
  336. spinlock_acquire(&lamebus->ls_lock);
  337. bits = read_ctl_register(lamebus, CTLREG_IRQE);
  338. bits |= mask;
  339. write_ctl_register(lamebus, CTLREG_IRQE, bits);
  340. spinlock_release(&lamebus->ls_lock);
  341. }
  342. /*
  343. * LAMEbus interrupt handling function. (Machine-independent!)
  344. */
  345. void
  346. lamebus_interrupt(struct lamebus_softc *lamebus)
  347. {
  348. /*
  349. * Note that despite the fact that "spl" stands for "set
  350. * priority level", we don't actually support interrupt
  351. * priorities. When an interrupt happens, we look through the
  352. * slots to find the first interrupting device and call its
  353. * interrupt routine, no matter what that device is.
  354. *
  355. * Note that the entire LAMEbus uses only one on-cpu interrupt line.
  356. * Thus, we do not use any on-cpu interrupt priority system either.
  357. */
  358. int slot;
  359. uint32_t mask;
  360. uint32_t irqs;
  361. void (*handler)(void *);
  362. void *data;
  363. /* For keeping track of how many bogus things happen in a row. */
  364. static int duds = 0;
  365. int duds_this_time = 0;
  366. /* and we better have a valid bus instance. */
  367. KASSERT(lamebus != NULL);
  368. /* Lock the softc */
  369. spinlock_acquire(&lamebus->ls_lock);
  370. /*
  371. * Read the LAMEbus controller register that tells us which
  372. * slots are asserting an interrupt condition.
  373. */
  374. irqs = read_ctl_register(lamebus, CTLREG_IRQS);
  375. if (irqs == 0) {
  376. /*
  377. * Huh? None of them? Must be a glitch.
  378. */
  379. kprintf("lamebus: stray interrupt on cpu %u\n",
  380. curcpu->c_number);
  381. duds++;
  382. duds_this_time++;
  383. /*
  384. * We could just return now, but instead we'll
  385. * continue ahead. Because irqs == 0, nothing in the
  386. * loop will execute, and passing through it gets us
  387. * to the code that checks how many duds we've
  388. * seen. This is important, because we just might get
  389. * a stray interrupt that latches itself on. If that
  390. * happens, we're pretty much toast, but it's better
  391. * to panic and hopefully reset the system than to
  392. * loop forever printing "stray interrupt".
  393. */
  394. }
  395. /*
  396. * Go through the bits in the value we got back to see which
  397. * ones are set.
  398. */
  399. for (mask=1, slot=0; slot<LB_NSLOTS; mask<<=1, slot++) {
  400. if ((irqs & mask) == 0) {
  401. /* Nope. */
  402. continue;
  403. }
  404. /*
  405. * This slot is signalling an interrupt.
  406. */
  407. if ((lamebus->ls_slotsinuse & mask)==0) {
  408. /*
  409. * No device driver is using this slot.
  410. */
  411. duds++;
  412. duds_this_time++;
  413. continue;
  414. }
  415. if (lamebus->ls_irqfuncs[slot]==NULL) {
  416. /*
  417. * The device driver hasn't installed an interrupt
  418. * handler.
  419. */
  420. duds++;
  421. duds_this_time++;
  422. continue;
  423. }
  424. /*
  425. * Call the interrupt handler. Release the spinlock
  426. * while we do so, in case other CPUs are handling
  427. * interrupts on other devices.
  428. */
  429. handler = lamebus->ls_irqfuncs[slot];
  430. data = lamebus->ls_devdata[slot];
  431. spinlock_release(&lamebus->ls_lock);
  432. handler(data);
  433. spinlock_acquire(&lamebus->ls_lock);
  434. /*
  435. * Reload the mask of pending IRQs - if we just called
  436. * hardclock, we might not have come back to this
  437. * context for some time, and it might have changed.
  438. */
  439. irqs = read_ctl_register(lamebus, CTLREG_IRQS);
  440. }
  441. /*
  442. * If we get interrupts for a slot with no driver or no
  443. * interrupt handler, it's fairly serious. Because LAMEbus
  444. * uses level-triggered interrupts, if we don't shut off the
  445. * condition, we'll keep getting interrupted continuously and
  446. * the system will make no progress. But we don't know how to
  447. * do that if there's no driver or no interrupt handler.
  448. *
  449. * So, if we get too many dud interrupts, panic, since it's
  450. * better to panic and reset than to hang.
  451. *
  452. * If we get through here without seeing any duds this time,
  453. * the condition, whatever it was, has gone away. It might be
  454. * some stupid device we don't have a driver for, or it might
  455. * have been an electrical transient. In any case, warn and
  456. * clear the dud count.
  457. */
  458. if (duds_this_time == 0 && duds > 0) {
  459. kprintf("lamebus: %d dud interrupts\n", duds);
  460. duds = 0;
  461. }
  462. if (duds > 10000) {
  463. panic("lamebus: too many (%d) dud interrupts\n", duds);
  464. }
  465. /* Unlock the softc */
  466. spinlock_release(&lamebus->ls_lock);
  467. }
  468. /*
  469. * Have the bus controller power the system off.
  470. */
  471. void
  472. lamebus_poweroff(struct lamebus_softc *lamebus)
  473. {
  474. /*
  475. * Write 0 to the power register to shut the system off.
  476. */
  477. cpu_irqoff();
  478. write_ctl_register(lamebus, CTLREG_PWR, 0);
  479. /* The power doesn't go off instantly... so halt the cpu. */
  480. cpu_halt();
  481. }
  482. /*
  483. * Ask the bus controller how much memory we have.
  484. */
  485. uint32_t
  486. lamebus_ramsize(void)
  487. {
  488. /*
  489. * Note that this has to work before bus initialization.
  490. * On machines where lamebus_read_register doesn't work
  491. * before bus initialization, this function can't be used
  492. * for initial RAM size lookup.
  493. */
  494. return read_ctl_register(NULL, CTLREG_RAMSZ);
  495. }
  496. /*
  497. * Turn on or off the interprocessor interrupt line for a given CPU.
  498. */
  499. void
  500. lamebus_assert_ipi(struct lamebus_softc *lamebus, struct cpu *target)
  501. {
  502. write_ctlcpu_register(lamebus, target->c_hardware_number,
  503. CTLCPU_CIPI, 1);
  504. }
  505. void
  506. lamebus_clear_ipi(struct lamebus_softc *lamebus, struct cpu *target)
  507. {
  508. write_ctlcpu_register(lamebus, target->c_hardware_number,
  509. CTLCPU_CIPI, 0);
  510. }
  511. /*
  512. * Initial setup.
  513. * Should be called from mainbus_bootstrap().
  514. */
  515. struct lamebus_softc *
  516. lamebus_init(void)
  517. {
  518. struct lamebus_softc *lamebus;
  519. int i;
  520. /* Allocate space for lamebus data */
  521. lamebus = kmalloc(sizeof(struct lamebus_softc));
  522. if (lamebus==NULL) {
  523. panic("lamebus_init: Out of memory\n");
  524. }
  525. spinlock_init(&lamebus->ls_lock);
  526. /*
  527. * Initialize the LAMEbus data structure.
  528. */
  529. lamebus->ls_slotsinuse = 1 << LB_CONTROLLER_SLOT;
  530. for (i=0; i<LB_NSLOTS; i++) {
  531. lamebus->ls_devdata[i] = NULL;
  532. lamebus->ls_irqfuncs[i] = NULL;
  533. }
  534. return lamebus;
  535. }