hw_cpu.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* This file is part of the program psim.
  2. Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #ifndef _HW_CPU_C_
  15. #define _HW_CPU_C_
  16. #ifndef STATIC_INLINE_HW_CPU
  17. #define STATIC_INLINE_HW_CPU STATIC_INLINE
  18. #endif
  19. #include "device_table.h"
  20. #include "hw_cpu.h"
  21. #include "interrupts.h"
  22. #include "cpu.h"
  23. /* DEVICE
  24. cpu - Interface to a Processor
  25. DESCRIPTION
  26. The CPU device provides the connection between the interrupt net
  27. (linking the devices and the interrupt controller) and the
  28. simulated model of each processor. This device contains interrupt
  29. ports that correspond directly to the external interrupt stimulus
  30. that can be sent to a given processor. Sending an interrupt to one
  31. of the ports results in an interrupt being delivered to the
  32. corresponding processor.
  33. Typically, an interrupt controller would have its inputs connected
  34. to device interrupt sources and its outputs (sreset, int, et.al.)
  35. connected to this device.
  36. PROPERTIES
  37. cpu-nr = <integer> (required)
  38. Specify the processor (1..N) that this cpu device node should
  39. control.
  40. EXAMPLES
  41. Connect an OpenPIC interrupt controller interrupt ports to
  42. processor zero.
  43. | -o '/phb/opic@0 > irq0 int /cpus/cpu@0' \
  44. | -o '/phb/opic@0 > init hreset /cpus/cpu@0' \
  45. */
  46. typedef struct _hw_cpu_device {
  47. int cpu_nr;
  48. cpu *processor;
  49. } hw_cpu_device;
  50. static const device_interrupt_port_descriptor hw_cpu_interrupt_ports[] = {
  51. { "hreset", hw_cpu_hard_reset },
  52. { "sreset", hw_cpu_soft_reset },
  53. { "int", hw_cpu_external_interrupt },
  54. { "mci", hw_cpu_machine_check_interrupt },
  55. { "smi", hw_cpu_system_management_interrupt },
  56. { NULL }
  57. };
  58. static void *
  59. hw_cpu_create(const char *name,
  60. const device_unit *unit_address,
  61. const char *args)
  62. {
  63. hw_cpu_device *hw_cpu = ZALLOC(hw_cpu_device);
  64. return hw_cpu;
  65. }
  66. /* during address initialization ensure that any missing cpu
  67. properties are added to this devices node */
  68. static void
  69. hw_cpu_init_address(device *me)
  70. {
  71. hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
  72. /* populate the node with properties */
  73. /* clear our data */
  74. memset(hw_cpu, 0x0, sizeof(hw_cpu_device));
  75. hw_cpu->cpu_nr = device_find_integer_property(me, "cpu-nr");
  76. hw_cpu->processor = psim_cpu(device_system(me), hw_cpu->cpu_nr);
  77. }
  78. /* Take the interrupt and synchronize its delivery with the clock. If
  79. we've not yet scheduled an interrupt for the next clock tick, take
  80. the oportunity to do it now */
  81. static void
  82. hw_cpu_interrupt_event(device *me,
  83. int my_port,
  84. device *source,
  85. int source_port,
  86. int level,
  87. cpu *processor,
  88. unsigned_word cia)
  89. {
  90. hw_cpu_device *hw_cpu = (hw_cpu_device*)device_data(me);
  91. if (my_port < 0 || my_port >= hw_cpu_nr_interrupt_ports)
  92. error("hw_cpu_interrupt_event_callback: interrupt port out of range %d\n",
  93. my_port);
  94. switch (my_port) {
  95. /*case hw_cpu_hard_reset:*/
  96. /*case hw_cpu_soft_reset:*/
  97. case hw_cpu_external_interrupt:
  98. external_interrupt(hw_cpu->processor, level);
  99. break;
  100. /*case hw_cpu_machine_check_interrupt:*/
  101. default:
  102. error("hw_cpu_deliver_interrupt: unimplemented interrupt port %d\n",
  103. my_port);
  104. break;
  105. }
  106. }
  107. static device_callbacks const hw_cpu_callbacks = {
  108. { hw_cpu_init_address, }, /* init */
  109. { NULL, }, /* address */
  110. { NULL, }, /* io */
  111. { NULL, }, /* DMA */
  112. { hw_cpu_interrupt_event, NULL, hw_cpu_interrupt_ports }, /* interrupts */
  113. { NULL, NULL, },
  114. };
  115. const device_descriptor hw_cpu_device_descriptor[] = {
  116. { "hw-cpu", hw_cpu_create, &hw_cpu_callbacks },
  117. { "cpu", hw_cpu_create, &hw_cpu_callbacks },
  118. { NULL, },
  119. };
  120. #endif /* _HW_CPU_C_ */