dev_cpc700.cc Source File

Back to the index.

dev_cpc700.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2009 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * COMMENT: IBM CPC700 bridge (PCI and interrupt controller)
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include "bus_pci.h"
36 #include "cpu.h"
37 #include "device.h"
38 #include "interrupt.h"
39 #include "machine.h"
40 #include "memory.h"
41 #include "misc.h"
42 
43 #include "thirdparty/cpc700reg.h"
44 
45 
46 struct cpc700_data {
47  struct interrupt ppc_irq; /* Connected to the CPU */
48 
49  uint32_t sr; /* Interrupt Status register */
50  uint32_t er; /* Interrupt Enable register */
51 
52  struct pci_data *pci_data; /* PCI bus */
53 };
54 
55 
57 {
58  struct cpc700_data *d = (struct cpc700_data *) interrupt->extra;
59  d->sr |= interrupt->line;
60  if (d->sr & d->er)
62 }
64 {
65  struct cpc700_data *d = (struct cpc700_data *) interrupt->extra;
66  d->sr &= ~interrupt->line;
67  if (!(d->sr & d->er))
69 }
70 
71 
72 /*
73  * dev_cpc700_pci_access():
74  *
75  * Passes PCI indirect addr and data accesses onto bus_pci.
76  */
77 DEVICE_ACCESS(cpc700_pci)
78 {
79  uint64_t idata = 0, odata = 0;
80  int bus, dev, func, reg;
81  struct cpc700_data *d = (struct cpc700_data *) extra;
82 
83  if (writeflag == MEM_WRITE)
85 
86  switch (relative_addr) {
87  case 0: /* Address: */
88  bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
89  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
90  break;
91 
92  case 4: /* Data: */
93  bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
94  &odata : &idata, len, writeflag);
95  break;
96  }
97 
98  if (writeflag == MEM_READ)
100 
101  return 1;
102 }
103 
104 
105 /*
106  * dev_cpc700_int_access():
107  *
108  * The interrupt controller.
109  */
110 DEVICE_ACCESS(cpc700_int)
111 {
112  struct cpc700_data *d = (struct cpc700_data *) extra;
113  uint64_t idata = 0, odata = 0;
114 
115  if (writeflag == MEM_WRITE)
116  idata = memory_readmax64(cpu, data, len);
117 
118  switch (relative_addr) {
119 
120  case CPC_UIC_SR:
121  /* Status register (cleared by writing ones): */
122  if (writeflag == MEM_READ) {
123  odata = d->sr;
124  } else {
125  d->sr &= ~idata;
126  if (!(d->sr & d->er))
128  }
129  break;
130 
131  case CPC_UIC_SRS:
132  /* Status register set: */
133  if (writeflag == MEM_READ) {
134  fatal("[ cpc700_int: read from CPC_UIC_SRS? ]\n");
135  odata = d->sr;
136  } else {
137  d->sr = idata;
138  if (d->sr & d->er)
140  else
142  }
143  break;
144 
145  case CPC_UIC_ER:
146  /* Enable register: */
147  if (writeflag == MEM_READ) {
148  odata = d->er;
149  } else {
150  d->er = idata;
151  if (d->sr & d->er)
153  else
155  }
156  break;
157 
158  case CPC_UIC_MSR:
159  /* Masked status: */
160  if (writeflag == MEM_READ) {
161  odata = d->sr & d->er;
162  } else {
163  fatal("[ cpc700_int: write to CPC_UIC_MSR? ]\n");
164  }
165  break;
166 
167  default:if (writeflag == MEM_WRITE) {
168  fatal("[ cpc700_int: unimplemented write to "
169  "offset 0x%x: data=0x%x ]\n", (int)
170  relative_addr, (int)idata);
171  } else {
172  fatal("[ cpc700_int: unimplemented read from "
173  "offset 0x%x ]\n", (int)relative_addr);
174  }
175  }
176 
177  if (writeflag == MEM_READ)
178  memory_writemax64(cpu, data, len, odata);
179 
180  return 1;
181 }
182 
183 
184 DEVINIT(cpc700)
185 {
186  struct cpc700_data *d;
187  char tmp[300];
188  int i;
189 
190  CHECK_ALLOCATION(d = (struct cpc700_data *) malloc(sizeof(struct cpc700_data)));
191  memset(d, 0, sizeof(struct cpc700_data));
192 
193  /* Connect to the CPU's interrupt pin: */
195 
196  /* Register 32 CPC700 interrupts: */
197  for (i=0; i<32; i++) {
198  struct interrupt templ;
199  char n[300];
200  snprintf(n, sizeof(n), "%s.cpc700.%i",
201  devinit->interrupt_path, i);
202  memset(&templ, 0, sizeof(templ));
203  templ.line = 1 << i;
204  templ.name = n;
205  templ.extra = d;
209  }
210 
211  /* Register a PCI bus: */
212  snprintf(tmp, sizeof(tmp), "%s.cpc700", devinit->interrupt_path);
213  d->pci_data = bus_pci_init(
214  devinit->machine,
215  tmp, /* pciirq path */
216  0, /* pci device io offset */
217  0, /* pci device mem offset */
218  CPC_PCI_IO_BASE, /* PCI portbase */
219  CPC_PCI_MEM_BASE, /* PCI membase: TODO */
220  tmp, /* PCI irqbase */
221  0, /* ISA portbase: TODO */
222  0, /* ISA membase: TODO */
223  tmp); /* ISA irqbase */
224 
225  switch (devinit->machine->machine_type) {
226 
227  case MACHINE_PMPPC:
229  devinit->machine->memory, 0, 0, 0, "heuricon_pmppc");
230  break;
231 
232  default:fatal("!\n! WARNING: cpc700 for non-implemented machine"
233  " type\n!\n");
234  exit(1);
235  }
236 
237  /* PCI configuration registers: */
239  CPC_PCICFGADR, 8, dev_cpc700_pci_access, d, DM_DEFAULT, NULL);
240 
241  /* Interrupt controller: */
243  CPC_UIC_BASE, CPC_UIC_SIZE, dev_cpc700_int_access, d,
244  DM_DEFAULT, NULL);
245 
246  /* Two serial ports: */
247  snprintf(tmp, sizeof(tmp), "ns16550 irq=%s.cpc700.%i addr=0x%llx "
248  "name2=tty0", devinit->interrupt_path, 31 - CPC_IB_UART_0,
249  (long long)CPC_COM0);
250  devinit->machine->main_console_handle = (size_t)
251  device_add(devinit->machine, tmp);
252  snprintf(tmp, sizeof(tmp), "ns16550 irq=%s.cpc700.%i addr=0x%llx "
253  "name2=tty1", devinit->interrupt_path, 31 - CPC_IB_UART_1,
254  (long long)CPC_COM1);
255  device_add(devinit->machine, tmp);
256 
258 
259  return 1;
260 }
261 
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
void fatal(const char *fmt,...)
Definition: main.cc:152
void(* interrupt_assert)(struct interrupt *)
Definition: interrupt.h:38
#define DM_DEFAULT
Definition: memory.h:130
#define CPC_UIC_SR
Definition: cpc700reg.h:119
int main_console_handle
Definition: machine.h:128
#define CPC_UIC_ER
Definition: cpc700reg.h:121
int machine_type
Definition: machine.h:111
void interrupt_handler_register(struct interrupt *templ)
Definition: interrupt.cc:81
#define MEM_READ
Definition: memory.h:116
void(* interrupt_deassert)(struct interrupt *)
Definition: interrupt.h:39
struct memory * memory
Definition: machine.h:126
void bus_pci_add(struct machine *machine, struct pci_data *pci_data, struct memory *mem, int bus, int device, int function, const char *name)
Definition: bus_pci.cc:216
#define CPC_UIC_MSR
Definition: cpc700reg.h:125
#define reg(x)
#define CPC_UIC_SRS
Definition: cpc700reg.h:120
void * return_ptr
Definition: device.h:56
#define CPC_PCI_IO_BASE
Definition: cpc700reg.h:48
void * device_add(struct machine *machine, const char *name_and_params)
Definition: device.cc:252
#define CPC_IB_UART_0
Definition: cpc700reg.h:139
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
DEVINIT(cpc700)
Definition: dev_cpc700.cc:184
uint32_t er
Definition: dev_cpc700.cc:50
void bus_pci_setaddr(struct cpu *cpu, struct pci_data *pci_data, int bus, int device, int function, int reg)
Definition: bus_pci.cc:196
struct interrupt ppc_irq
Definition: dev_cpc700.cc:47
u_short data
Definition: siireg.h:79
#define CPC_PCI_MEM_BASE
Definition: cpc700reg.h:44
#define INTERRUPT_ASSERT(istruct)
Definition: interrupt.h:74
#define MEM_WRITE
Definition: memory.h:117
Definition: device.h:40
DEVICE_ACCESS(cpc700_pci)
Definition: dev_cpc700.cc:77
uint32_t line
Definition: interrupt.h:51
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
Definition: cpu.h:326
struct machine * machine
Definition: device.h:41
uint32_t sr
Definition: dev_cpc700.cc:49
char * name
Definition: interrupt.h:66
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
#define CPC_COM1
Definition: cpc700reg.h:91
void cpc700_interrupt_deassert(struct interrupt *interrupt)
Definition: dev_cpc700.cc:63
#define CPC_PCICFGADR
Definition: cpc700reg.h:53
void memory_device_register(struct memory *mem, const char *, uint64_t baseaddr, uint64_t len, int(*f)(struct cpu *, struct memory *, uint64_t, unsigned char *, size_t, int, void *), void *extra, int flags, unsigned char *dyntrans_data)
Definition: memory.cc:339
void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
Definition: bus_pci.cc:76
struct pci_data * bus_pci_init(struct machine *machine, const char *irq_path, uint64_t pci_actual_io_offset, uint64_t pci_actual_mem_offset, uint64_t pci_portbase, uint64_t pci_membase, const char *pci_irqbase, uint64_t isa_portbase, uint64_t isa_membase, const char *isa_irqbase)
Definition: bus_pci.cc:355
addr & if(addr >=0x24 &&page !=NULL)
#define CPC_COM0
Definition: cpc700reg.h:90
struct pci_data * pci_data
Definition: dev_cpc700.cc:52
#define MACHINE_PMPPC
Definition: machine.h:227
void * extra
Definition: interrupt.h:59
void bus_pci_data_access(struct cpu *cpu, struct pci_data *pci_data, uint64_t *data, int len, int writeflag)
Definition: bus_pci.cc:95
#define MEM_PCI_LITTLE_ENDIAN
Definition: memory.h:97
void cpc700_interrupt_assert(struct interrupt *interrupt)
Definition: dev_cpc700.cc:56
#define CPC_UIC_BASE
Definition: cpc700reg.h:117
char * interrupt_path
Definition: device.h:50
#define CPC_UIC_SIZE
Definition: cpc700reg.h:118
#define INTERRUPT_DEASSERT(istruct)
Definition: interrupt.h:75
#define CPC_IB_UART_1
Definition: cpc700reg.h:140

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13