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