macebus.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /* $OpenBSD: macebus.c,v 1.63 2014/09/30 06:51:58 jmatthew Exp $ */
  2. /*
  3. * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
  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. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  15. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24. * SUCH DAMAGE.
  25. *
  26. */
  27. /*
  28. * This is a combined macebus/crimebus driver. It handles configuration of all
  29. * devices on the processor bus.
  30. */
  31. #include <sys/param.h>
  32. #include <sys/systm.h>
  33. #include <sys/kernel.h>
  34. #include <sys/conf.h>
  35. #include <sys/malloc.h>
  36. #include <sys/device.h>
  37. #include <sys/proc.h>
  38. #include <sys/atomic.h>
  39. #include <mips64/archtype.h>
  40. #include <mips64/mips_cpu.h>
  41. #include <machine/autoconf.h>
  42. #include <machine/intr.h>
  43. #include <sgi/localbus/crimebus.h>
  44. #include <sgi/localbus/macebus.h>
  45. #include <sgi/localbus/macebusvar.h>
  46. int macebusmatch(struct device *, void *, void *);
  47. void macebusattach(struct device *, struct device *, void *);
  48. int macebusprint(void *, const char *);
  49. int macebussubmatch(struct device *, void *, void *);
  50. void macebus_intr_makemasks(void);
  51. void macebus_splx(int);
  52. uint32_t macebus_iointr(uint32_t, struct trap_frame *);
  53. uint32_t macebus_aux(uint32_t, struct trap_frame *);
  54. int macebus_iointr_skip(struct intrhand *, uint64_t, uint64_t);
  55. void crime_setintrmask(int);
  56. u_int8_t mace_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
  57. u_int16_t mace_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
  58. u_int32_t mace_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
  59. u_int64_t mace_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
  60. void mace_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  61. u_int8_t);
  62. void mace_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  63. u_int16_t);
  64. void mace_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  65. u_int32_t);
  66. void mace_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  67. u_int64_t);
  68. void mace_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  69. u_int8_t *, bus_size_t);
  70. void mace_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  71. const u_int8_t *, bus_size_t);
  72. void mace_read_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  73. u_int8_t *, bus_size_t);
  74. void mace_write_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  75. const u_int8_t *, bus_size_t);
  76. void mace_read_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  77. u_int8_t *, bus_size_t);
  78. void mace_write_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
  79. const u_int8_t *, bus_size_t);
  80. int mace_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
  81. bus_space_handle_t *);
  82. void mace_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
  83. int mace_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  84. bus_size_t, bus_space_handle_t *);
  85. void *mace_space_vaddr(bus_space_tag_t, bus_space_handle_t);
  86. void mace_space_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t,
  87. bus_size_t, int);
  88. bus_addr_t macebus_pa_to_device(paddr_t);
  89. paddr_t macebus_device_to_pa(bus_addr_t);
  90. struct cfattach macebus_ca = {
  91. sizeof(struct device), macebusmatch, macebusattach
  92. };
  93. struct cfdriver macebus_cd = {
  94. NULL, "macebus", DV_DULL
  95. };
  96. bus_space_t macebus_tag = {
  97. PHYS_TO_XKPHYS(MACEBUS_BASE, CCA_NC),
  98. NULL,
  99. mace_read_1, mace_write_1,
  100. mace_read_2, mace_write_2,
  101. mace_read_4, mace_write_4,
  102. mace_read_8, mace_write_8,
  103. mace_read_raw_2, mace_write_raw_2,
  104. mace_read_raw_4, mace_write_raw_4,
  105. mace_read_raw_8, mace_write_raw_8,
  106. mace_space_map, mace_space_unmap, mace_space_region,
  107. mace_space_vaddr, mace_space_barrier
  108. };
  109. bus_space_t crimebus_tag = {
  110. PHYS_TO_XKPHYS(CRIMEBUS_BASE, CCA_NC),
  111. NULL,
  112. mace_read_1, mace_write_1,
  113. mace_read_2, mace_write_2,
  114. mace_read_4, mace_write_4,
  115. mace_read_8, mace_write_8,
  116. mace_read_raw_2, mace_write_raw_2,
  117. mace_read_raw_4, mace_write_raw_4,
  118. mace_read_raw_8, mace_write_raw_8,
  119. mace_space_map, mace_space_unmap, mace_space_region,
  120. mace_space_vaddr, mace_space_barrier
  121. };
  122. bus_space_handle_t crime_h;
  123. bus_space_handle_t mace_h;
  124. struct machine_bus_dma_tag mace_bus_dma_tag = {
  125. NULL, /* _cookie */
  126. _dmamap_create,
  127. _dmamap_destroy,
  128. _dmamap_load,
  129. _dmamap_load_mbuf,
  130. _dmamap_load_uio,
  131. _dmamap_load_raw,
  132. _dmamap_load_buffer,
  133. _dmamap_unload,
  134. _dmamap_sync,
  135. _dmamem_alloc,
  136. _dmamem_free,
  137. _dmamem_map,
  138. _dmamem_unmap,
  139. _dmamem_mmap,
  140. macebus_pa_to_device,
  141. macebus_device_to_pa,
  142. CRIME_MEMORY_MASK
  143. };
  144. /*
  145. * CRIME/MACE interrupt handling declarations: 32 CRIME sources, 32 MACE
  146. * sources (multiplexed by CRIME); 1 level.
  147. * We define another level for periodic tasks as well.
  148. */
  149. struct crime_intrhand {
  150. struct intrhand ih;
  151. uint32_t mace_irqmask;
  152. };
  153. struct crime_intrhand *crime_intrhand[CRIME_NINTS];
  154. #define INTPRI_MACEIO (INTPRI_CLOCK + 1)
  155. #define INTPRI_MACEAUX (INTPRI_MACEIO + 1)
  156. uint64_t crime_intem, mace_intem;
  157. uint64_t crime_imask[NIPLS];
  158. /*
  159. * List of macebus child devices.
  160. */
  161. #define MACEBUSDEV(name, addr, i, i2) \
  162. { name, &macebus_tag, &macebus_tag, &mace_bus_dma_tag, addr, i, i2 }
  163. struct macebus_attach_args macebus_children[] = {
  164. MACEBUSDEV("com", MACE_ISA_SER1_OFFS, 4, MACE_ISA_INT_SERIAL_1),
  165. MACEBUSDEV("com", MACE_ISA_SER2_OFFS, 4, MACE_ISA_INT_SERIAL_2),
  166. MACEBUSDEV("dsrtc", MACE_ISA_RTC_OFFS, -1, 0),
  167. #if 0
  168. MACEBUSDEV("lpt", MACE_ISA_EPP_OFFS, 4, MACE_ISA_INT_PARALLEL),
  169. #endif
  170. MACEBUSDEV("macepcibr", MACE_PCI_OFFS, 7, 0),
  171. MACEBUSDEV("mavb", MACE_IO_AUDIO_OFFS, 6, MACE_ISA_INT_AUDIO),
  172. MACEBUSDEV("mec", MACE_ETHERNET_OFFS, 3, 0),
  173. MACEBUSDEV("mkbc", MACE_IO_KBC_OFFS, 5,
  174. MACE_ISA_INT_KBD | MACE_ISA_INT_KBD_POLL |
  175. MACE_ISA_INT_MOUSE | MACE_ISA_INT_MOUSE_POLL),
  176. MACEBUSDEV("power", 0, 5, MACE_ISA_INT_RTC)
  177. };
  178. #undef MACEBUSDEV
  179. /*
  180. * Match bus only to targets which have this bus.
  181. */
  182. int
  183. macebusmatch(struct device *parent, void *match, void *aux)
  184. {
  185. if (sys_config.system_type == SGI_O2)
  186. return (1);
  187. return (0);
  188. }
  189. int
  190. macebusprint(void *aux, const char *macebus)
  191. {
  192. struct macebus_attach_args *maa = aux;
  193. if (macebus != NULL)
  194. printf("%s at %s", maa->maa_name, macebus);
  195. if (maa->maa_baseaddr != 0)
  196. printf(" base 0x%08lx", maa->maa_baseaddr);
  197. if (maa->maa_intr >= 0)
  198. printf(" irq %d", maa->maa_intr);
  199. return (UNCONF);
  200. }
  201. int
  202. macebussubmatch(struct device *parent, void *vcf, void *args)
  203. {
  204. struct cfdata *cf = vcf;
  205. struct macebus_attach_args *maa = args;
  206. if (strcmp(cf->cf_driver->cd_name, maa->maa_name) != 0)
  207. return 0;
  208. if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)maa->maa_baseaddr)
  209. return 0;
  210. return (*cf->cf_attach->ca_match)(parent, cf, maa);
  211. }
  212. void
  213. macebusattach(struct device *parent, struct device *self, void *aux)
  214. {
  215. u_int32_t creg;
  216. uint i;
  217. /*
  218. * Map and setup CRIME control registers.
  219. */
  220. if (bus_space_map(&crimebus_tag, 0x00000000, 0x400, 0, &crime_h)) {
  221. printf(": can't map CRIME control registers\n");
  222. return;
  223. }
  224. creg = bus_space_read_8(&crimebus_tag, crime_h, CRIME_REVISION);
  225. printf(": crime rev %d.%d\n", (creg & 0xf0) >> 4, creg & 0xf);
  226. bus_space_write_8(&crimebus_tag, crime_h, CRIME_CPU_ERROR_STAT, 0);
  227. bus_space_write_8(&crimebus_tag, crime_h, CRIME_MEM_ERROR_STAT, 0);
  228. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, 0);
  229. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_SOFT, 0);
  230. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_HARD, 0);
  231. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_STAT, 0);
  232. /*
  233. * Map and setup MACE ISA control registers.
  234. */
  235. if (bus_space_map(&macebus_tag, MACE_ISA_OFFS, 0x400, 0, &mace_h)) {
  236. printf("%s: can't map MACE control registers\n",
  237. self->dv_xname);
  238. return;
  239. }
  240. bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_MASK, 0);
  241. bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_STAT, 0);
  242. /*
  243. * On O2 systems all interrupts are handled by the macebus interrupt
  244. * handler. Register all except clock.
  245. */
  246. set_intr(INTPRI_MACEIO, CR_INT_0, macebus_iointr);
  247. register_splx_handler(macebus_splx);
  248. /* Set up a handler called when clock interrupts go off. */
  249. set_intr(INTPRI_MACEAUX, CR_INT_5, macebus_aux);
  250. /*
  251. * Attach subdevices.
  252. */
  253. for (i = 0; i < nitems(macebus_children); i++)
  254. config_found_sm(self, macebus_children + i,
  255. macebusprint, macebussubmatch);
  256. }
  257. /*
  258. * Bus access primitives. These are really ugly...
  259. */
  260. u_int8_t
  261. mace_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
  262. {
  263. return *(volatile u_int8_t *)(h + (o << 8) + 7);
  264. }
  265. u_int16_t
  266. mace_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
  267. {
  268. panic(__func__);
  269. }
  270. u_int32_t
  271. mace_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
  272. {
  273. return *(volatile u_int32_t *)(h + o);
  274. }
  275. u_int64_t
  276. mace_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
  277. {
  278. return *(volatile u_int64_t *)(h + o);
  279. }
  280. void
  281. mace_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
  282. {
  283. *(volatile u_int8_t *)(h + (o << 8) + 7) = v;
  284. }
  285. void
  286. mace_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v)
  287. {
  288. panic(__func__);
  289. }
  290. void
  291. mace_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v)
  292. {
  293. *(volatile u_int32_t *)(h + o) = v;
  294. }
  295. void
  296. mace_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v)
  297. {
  298. *(volatile u_int64_t *)(h + o) = v;
  299. }
  300. void
  301. mace_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  302. u_int8_t *buf, bus_size_t len)
  303. {
  304. panic(__func__);
  305. }
  306. void
  307. mace_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  308. const u_int8_t *buf, bus_size_t len)
  309. {
  310. panic(__func__);
  311. }
  312. void
  313. mace_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  314. u_int8_t *buf, bus_size_t len)
  315. {
  316. volatile u_int32_t *addr = (volatile u_int32_t *)(h + o);
  317. len >>= 2;
  318. while (len-- != 0) {
  319. *(u_int32_t *)buf = *addr;
  320. buf += 4;
  321. }
  322. }
  323. void
  324. mace_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  325. const u_int8_t *buf, bus_size_t len)
  326. {
  327. volatile u_int32_t *addr = (volatile u_int32_t *)(h + o);
  328. len >>= 2;
  329. while (len-- != 0) {
  330. *addr = *(u_int32_t *)buf;
  331. buf += 4;
  332. }
  333. }
  334. void
  335. mace_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  336. u_int8_t *buf, bus_size_t len)
  337. {
  338. volatile u_int64_t *addr = (volatile u_int64_t *)(h + o);
  339. len >>= 3;
  340. while (len-- != 0) {
  341. *(u_int64_t *)buf = *addr;
  342. buf += 8;
  343. }
  344. }
  345. void
  346. mace_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
  347. const u_int8_t *buf, bus_size_t len)
  348. {
  349. volatile u_int64_t *addr = (volatile u_int64_t *)(h + o);
  350. len >>= 3;
  351. while (len-- != 0) {
  352. *addr = *(u_int64_t *)buf;
  353. buf += 8;
  354. }
  355. }
  356. int
  357. mace_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
  358. int flags, bus_space_handle_t *bshp)
  359. {
  360. if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE))
  361. offs +=
  362. PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
  363. *bshp = t->bus_base + offs;
  364. return 0;
  365. }
  366. void
  367. mace_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
  368. {
  369. }
  370. int
  371. mace_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
  372. bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
  373. {
  374. *nbshp = bsh + offset;
  375. return (0);
  376. }
  377. void *
  378. mace_space_vaddr(bus_space_tag_t t, bus_space_handle_t h)
  379. {
  380. return (void *)h;
  381. }
  382. void
  383. mace_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offs,
  384. bus_size_t len, int flags)
  385. {
  386. mips_sync();
  387. }
  388. /*
  389. * Macebus bus_dma helpers.
  390. * Mace accesses memory contiguously at 0x40000000 onwards.
  391. */
  392. bus_addr_t
  393. macebus_pa_to_device(paddr_t pa)
  394. {
  395. return (pa | CRIME_MEMORY_OFFSET);
  396. }
  397. paddr_t
  398. macebus_device_to_pa(bus_addr_t addr)
  399. {
  400. paddr_t pa = (paddr_t)addr & CRIME_MEMORY_MASK;
  401. if (pa >= 256 * 1024 * 1024)
  402. pa |= CRIME_MEMORY_OFFSET;
  403. return (pa);
  404. }
  405. /*
  406. * Macebus interrupt handler driver.
  407. */
  408. /*
  409. * Establish an interrupt handler called from the dispatcher.
  410. * The interrupt function established should return zero if there was nothing
  411. * to serve (no int) and non-zero when an interrupt was serviced.
  412. *
  413. * Interrupts are numbered from 1 and up where 1 maps to HW int 0.
  414. * XXX There is no reason to keep this... except for hardcoded interrupts
  415. * XXX in kernel configuration files...
  416. */
  417. void *
  418. macebus_intr_establish(int irq, uint32_t mace_irqmask, int type, int level,
  419. int (*ih_fun)(void *), void *ih_arg, const char *ih_what)
  420. {
  421. struct crime_intrhand **p, *q, *ih;
  422. int s;
  423. #ifdef DIAGNOSTIC
  424. if (irq >= CRIME_NINTS || irq < 0)
  425. panic("intr_establish: illegal irq %d", irq);
  426. #endif
  427. ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
  428. if (ih == NULL)
  429. return NULL;
  430. ih->ih.ih_next = NULL;
  431. ih->ih.ih_fun = ih_fun;
  432. ih->ih.ih_arg = ih_arg;
  433. ih->ih.ih_level = level;
  434. ih->ih.ih_irq = irq;
  435. ih->mace_irqmask = mace_irqmask;
  436. evcount_attach(&ih->ih.ih_count, ih_what, &ih->ih.ih_irq);
  437. s = splhigh();
  438. /*
  439. * Figure out where to put the handler.
  440. * This is O(N^2), but we want to preserve the order, and N is
  441. * generally small.
  442. */
  443. for (p = &crime_intrhand[irq]; (q = *p) != NULL;
  444. p = (struct crime_intrhand **)&q->ih.ih_next)
  445. ;
  446. *p = ih;
  447. crime_intem |= 1UL << irq;
  448. macebus_intr_makemasks();
  449. /* enable further MACE sources if necessary */
  450. if (mace_irqmask != 0) {
  451. mace_intem |= mace_irqmask;
  452. bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_MASK,
  453. mace_intem);
  454. }
  455. splx(s); /* causes hw mask update */
  456. return (ih);
  457. }
  458. void
  459. macebus_intr_disestablish(void *ih)
  460. {
  461. /* XXX */
  462. panic("%s not implemented", __func__);
  463. }
  464. void
  465. macebus_splx(int newipl)
  466. {
  467. struct cpu_info *ci = curcpu();
  468. /* Update masks to new ipl. Order highly important! */
  469. __asm__ (".set noreorder\n");
  470. ci->ci_ipl = newipl;
  471. mips_sync();
  472. __asm__ (".set reorder\n");
  473. crime_setintrmask(newipl);
  474. /* If we still have softints pending trigger processing. */
  475. if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
  476. setsoftintr0();
  477. }
  478. /*
  479. * Crime interrupt handler.
  480. */
  481. #define INTR_FUNCTIONNAME macebus_iointr
  482. #define MASK_FUNCTIONNAME macebus_intr_makemasks
  483. #define INTR_LOCAL_DECLS \
  484. uint64_t mace_isr, mace_imr;
  485. #define MASK_LOCAL_DECLS
  486. #define INTR_GETMASKS \
  487. do { \
  488. isr = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_STAT); \
  489. imr = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_MASK); \
  490. if (((CRIME_INT_SUPER_IO | CRIME_INT_SUB_MISC | CRIME_INT_SUB_AUDIO) & \
  491. isr & imr) != 0) { \
  492. mace_isr = bus_space_read_8(&macebus_tag, mace_h, \
  493. MACE_ISA_INT_STAT); \
  494. mace_imr = bus_space_read_8(&macebus_tag, mace_h, \
  495. MACE_ISA_INT_MASK); \
  496. } else \
  497. mace_isr = mace_imr = 0; \
  498. bit = 63; \
  499. } while (0)
  500. #define INTR_MASKPENDING \
  501. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, imr & ~isr)
  502. #define INTR_IMASK(ipl) crime_imask[ipl]
  503. #define INTR_HANDLER(bit) (struct intrhand *)crime_intrhand[bit]
  504. #define INTR_SPURIOUS(bit) \
  505. do { \
  506. if (((CRIME_INT_SUPER_IO | CRIME_INT_SUB_MISC | CRIME_INT_SUB_AUDIO) & \
  507. (1 << (bit))) != 0) { \
  508. if ((mace_isr & mace_imr) != 0) \
  509. printf("spurious crime interrupt %d" \
  510. " mace isr %p imr %p\n", \
  511. bit, (void *)mace_isr, (void *)mace_imr); \
  512. } else \
  513. printf("spurious crime interrupt %d\n", bit); \
  514. } while (0)
  515. #define INTR_MASKRESTORE \
  516. bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, imr)
  517. #define INTR_MASKSIZE CRIME_NINTS
  518. #define INTR_HANDLER_SKIP(ih) \
  519. macebus_iointr_skip((void *)ih, mace_isr, mace_imr)
  520. #include <sgi/sgi/intr_template.c>
  521. int
  522. macebus_iointr_skip(struct intrhand *ih, uint64_t mace_isr, uint64_t mace_imr)
  523. {
  524. struct crime_intrhand *mih = (struct crime_intrhand *)ih;
  525. /* do not skip pure CRIME interrupts */
  526. if (mih->mace_irqmask == 0)
  527. return 0;
  528. /*
  529. * Several CRIME interrupts (such as superio and miscellaneous) are
  530. * shared by multiple devices, so narrow the selection with the
  531. * MACE interrupt status.
  532. */
  533. if ((mace_isr & mace_imr & mih->mace_irqmask) != 0)
  534. return 0;
  535. return 1;
  536. }
  537. /*
  538. * Macebus auxilary functions run each clock interrupt.
  539. */
  540. uint32_t
  541. macebus_aux(uint32_t hwpend, struct trap_frame *cf)
  542. {
  543. u_int64_t mask;
  544. mask = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG);
  545. mask |= MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF;
  546. /* GREEN - Idle */
  547. /* AMBER - System mode */
  548. /* RED - User mode */
  549. if (cf->sr & SR_KSU_USER) {
  550. mask &= ~MACE_ISA_MISC_RLED_OFF;
  551. } else if (curproc == NULL ||
  552. curproc == curcpu()->ci_schedstate.spc_idleproc) {
  553. mask &= ~MACE_ISA_MISC_GLED_OFF;
  554. } else {
  555. mask &= ~(MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF);
  556. }
  557. bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG, mask);
  558. return 0; /* Real clock int handler will claim the interrupt. */
  559. }
  560. void
  561. crime_setintrmask(int level)
  562. {
  563. *(volatile uint64_t *)(PHYS_TO_XKPHYS(CRIMEBUS_BASE, CCA_NC) +
  564. CRIME_INT_MASK) = crime_intem & ~crime_imask[level];
  565. }