lamebus_machdep.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. #include <types.h>
  30. #include <kern/unistd.h>
  31. #include <lib.h>
  32. #include <mips/trapframe.h>
  33. #include <cpu.h>
  34. #include <spl.h>
  35. #include <clock.h>
  36. #include <thread.h>
  37. #include <current.h>
  38. #include <synch.h>
  39. #include <mainbus.h>
  40. #include <sys161/bus.h>
  41. #include <lamebus/lamebus.h>
  42. #include "autoconf.h"
  43. /*
  44. * CPU frequency used by the on-chip timer.
  45. *
  46. * Note that we really ought to measure the CPU frequency against the
  47. * real-time clock instead of compiling it in like this.
  48. */
  49. #define CPU_FREQUENCY 25000000 /* 25 MHz */
  50. /*
  51. * Access to the on-chip timer.
  52. *
  53. * The c0_count register increments on every cycle; when the value
  54. * matches the c0_compare register, the timer interrupt line is
  55. * asserted. Writing to c0_compare again clears the interrupt.
  56. */
  57. static
  58. void
  59. mips_timer_set(uint32_t count)
  60. {
  61. /*
  62. * $11 == c0_compare; we can't use the symbolic name inside
  63. * the asm string.
  64. */
  65. __asm volatile(
  66. ".set push;" /* save assembler mode */
  67. ".set mips32;" /* allow MIPS32 registers */
  68. "mtc0 %0, $11;" /* do it */
  69. ".set pop" /* restore assembler mode */
  70. :: "r" (count));
  71. }
  72. /*
  73. * LAMEbus data for the system. (We have only one LAMEbus per system.)
  74. * This does not need to be locked, because it's constant once
  75. * initialized, and initialized before we start other threads or CPUs.
  76. */
  77. static struct lamebus_softc *lamebus;
  78. void
  79. mainbus_bootstrap(void)
  80. {
  81. /* Interrupts should be off (and have been off since startup) */
  82. KASSERT(curthread->t_curspl > 0);
  83. /* Initialize the system LAMEbus data */
  84. lamebus = lamebus_init();
  85. /* Probe CPUs (should these be done as device attachments instead?) */
  86. lamebus_find_cpus(lamebus);
  87. /*
  88. * Print the device name for the main bus.
  89. */
  90. kprintf("lamebus0 (system main bus)\n");
  91. /*
  92. * Now we can take interrupts without croaking, so turn them on.
  93. * Some device probes might require being able to get interrupts.
  94. */
  95. spl0();
  96. /*
  97. * Now probe all the devices attached to the bus.
  98. * (This amounts to all devices.)
  99. */
  100. autoconf_lamebus(lamebus, 0);
  101. /*
  102. * Configure the MIPS on-chip timer to interrupt HZ times a second.
  103. */
  104. mips_timer_set(CPU_FREQUENCY / HZ);
  105. }
  106. /*
  107. * Start all secondary CPUs.
  108. */
  109. void
  110. mainbus_start_cpus(void)
  111. {
  112. lamebus_start_cpus(lamebus);
  113. }
  114. /*
  115. * Function to generate the memory address (in the uncached segment)
  116. * for the specified offset into the specified slot's region of the
  117. * LAMEbus.
  118. */
  119. void *
  120. lamebus_map_area(struct lamebus_softc *bus, int slot, uint32_t offset)
  121. {
  122. uint32_t address;
  123. (void)bus; // not needed
  124. KASSERT(slot >= 0 && slot < LB_NSLOTS);
  125. address = LB_BASEADDR + slot*LB_SLOT_SIZE + offset;
  126. return (void *)address;
  127. }
  128. /*
  129. * Read a 32-bit register from a LAMEbus device.
  130. */
  131. uint32_t
  132. lamebus_read_register(struct lamebus_softc *bus, int slot, uint32_t offset)
  133. {
  134. uint32_t *ptr = lamebus_map_area(bus, slot, offset);
  135. return *ptr;
  136. }
  137. /*
  138. * Write a 32-bit register of a LAMEbus device.
  139. */
  140. void
  141. lamebus_write_register(struct lamebus_softc *bus, int slot,
  142. uint32_t offset, uint32_t val)
  143. {
  144. uint32_t *ptr = lamebus_map_area(bus, slot, offset);
  145. *ptr = val;
  146. }
  147. /*
  148. * Power off the system.
  149. */
  150. void
  151. mainbus_poweroff(void)
  152. {
  153. /*
  154. *
  155. * Note that lamebus_write_register() doesn't actually access
  156. * the bus argument, so this will still work if we get here
  157. * before the bus is initialized.
  158. */
  159. lamebus_poweroff(lamebus);
  160. }
  161. /*
  162. * Reboot the system.
  163. */
  164. void
  165. mainbus_reboot(void)
  166. {
  167. /*
  168. * The MIPS doesn't appear to have any on-chip reset.
  169. * LAMEbus doesn't have a reset control, so we just
  170. * power off instead of rebooting. This would not be
  171. * so great in a real system, but it's fine for what
  172. * we're doing.
  173. */
  174. kprintf("Cannot reboot - powering off instead, sorry.\n");
  175. mainbus_poweroff();
  176. }
  177. /*
  178. * Halt the system.
  179. * On some systems, this would return to the boot monitor. But we don't
  180. * have one.
  181. */
  182. void
  183. mainbus_halt(void)
  184. {
  185. cpu_halt();
  186. }
  187. /*
  188. * Called to reset the system from panic().
  189. *
  190. * By the time we get here, the system may well be sufficiently hosed
  191. * as to panic recursively if we do much of anything. So just power off.
  192. * (We'd reboot, but System/161 doesn't do that.)
  193. */
  194. void
  195. mainbus_panic(void)
  196. {
  197. mainbus_poweroff();
  198. }
  199. /*
  200. * Function to get the size of installed physical RAM from the LAMEbus
  201. * controller.
  202. */
  203. uint32_t
  204. mainbus_ramsize(void)
  205. {
  206. return lamebus_ramsize();
  207. }
  208. /*
  209. * Send IPI.
  210. */
  211. void
  212. mainbus_send_ipi(struct cpu *target)
  213. {
  214. lamebus_assert_ipi(lamebus, target);
  215. }
  216. /*
  217. * Interrupt dispatcher.
  218. */
  219. /* Wiring of LAMEbus interrupts to bits in the cause register */
  220. #define LAMEBUS_IRQ_BIT 0x00000400 /* all system bus slots */
  221. #define LAMEBUS_IPI_BIT 0x00000800 /* inter-processor interrupt */
  222. #define MIPS_TIMER_BIT 0x00008000 /* on-chip timer */
  223. void
  224. mainbus_interrupt(struct trapframe *tf)
  225. {
  226. uint32_t cause;
  227. /* interrupts should be off */
  228. KASSERT(curthread->t_curspl > 0);
  229. cause = tf->tf_cause;
  230. if (cause & LAMEBUS_IRQ_BIT) {
  231. lamebus_interrupt(lamebus);
  232. }
  233. else if (cause & LAMEBUS_IPI_BIT) {
  234. interprocessor_interrupt();
  235. lamebus_clear_ipi(lamebus, curcpu);
  236. }
  237. else if (cause & MIPS_TIMER_BIT) {
  238. /* Reset the timer (this clears the interrupt) */
  239. mips_timer_set(CPU_FREQUENCY / HZ);
  240. /* and call hardclock */
  241. hardclock();
  242. }
  243. else {
  244. panic("Unknown interrupt; cause register is %08x\n", cause);
  245. }
  246. }