dev_gt.cc Source File

Back to the index.

dev_gt.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2010 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: Galileo Technology GT-64xxx PCI controller
29  *
30  * GT-64011 Used in Cobalt machines.
31  * GT-64120 Used in evbmips machines (Malta).
32  * GT-64260 Used in mvmeppc machines.
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #include "bus_pci.h"
40 #include "cpu.h"
41 #include "devices.h"
42 #include "interrupt.h"
43 #include "machine.h"
44 #include "memory.h"
45 #include "misc.h"
46 #include "timer.h"
47 
48 #include "thirdparty/gtreg.h"
49 
50 
51 #define TICK_SHIFT 14
52 
53 /* #define debug fatal */
54 
55 #define PCI_PRODUCT_GALILEO_GT64011 0x4146 /* GT-64011 */
56 #define PCI_PRODUCT_GALILEO_GT64120 0x4620 /* GT-64120 */
57 #define PCI_PRODUCT_GALILEO_GT64260 0x6430 /* GT-64260 */
58 
59 
60 struct gt_data {
61  int type;
62 
63  struct timer *timer;
67 
68  /* Address decode registers: */
70 
71  struct pci_data *pci_data;
72 };
73 
74 
75 /*
76  * timer_tick():
77  *
78  * Called d->interrupt_hz times per (real-world) second.
79  */
80 static void timer_tick(struct timer *timer, void *extra)
81 {
82  struct gt_data *d = (struct gt_data *) extra;
84 }
85 
86 
88 {
89  struct gt_data *d = (struct gt_data *) extra;
90  if (d->pending_timer0_interrupts > 0)
92 }
93 
94 
96 {
97  struct gt_data *d = (struct gt_data *) extra;
98  uint64_t idata = 0, odata = 0;
99  int bus, dev, func, reg;
100  size_t i;
101 
102  if (writeflag == MEM_WRITE)
103  idata = memory_readmax64(cpu, data, len);
104 
105  switch (relative_addr) {
106 
107  case GT_PCI0IOLD_OFS:
108  case GT_PCI0IOHD_OFS:
109  case GT_PCI0M0LD_OFS:
110  case GT_PCI0M0HD_OFS:
111  case GT_PCI0M1LD_OFS:
112  case GT_PCI0M1HD_OFS:
113  case GT_PCI0IOREMAP_OFS:
114  case GT_PCI0M0REMAP_OFS:
115  case GT_PCI0M1REMAP_OFS:
116  if (writeflag == MEM_READ) {
117  odata = d->decode[relative_addr / 8];
118  debug("[ gt: read from offset 0x%x: 0x%x ]\n",
119  (int)relative_addr, (int)odata);
120  } else {
121  d->decode[relative_addr / 8] = idata;
122  fatal("[ gt: write to offset 0x%x: 0x%x (TODO) ]\n",
123  (int)relative_addr, (int)idata);
124  }
125  break;
126 
127  case GT_PCI0_CMD_OFS:
128  if (writeflag == MEM_WRITE) {
129  debug("[ gt: write to GT_PCI0_CMD: 0x%08x (TODO) ]\n",
130  (int)idata);
131  } else {
132  debug("[ gt: read from GT_PCI0_CMD (0x%08x) (TODO) ]\n",
133  (int)odata);
134  }
135  break;
136 
137  case GT_INTR_CAUSE:
138  if (writeflag == MEM_WRITE) {
139  debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
140  (int)idata);
141  return 1;
142  } else {
143  odata = GTIC_T0EXP;
145 
146  if (d->pending_timer0_interrupts > 0)
148 
149  debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
150  (int)odata);
151  }
152  break;
153 
154  case GT_PCI0_INTR_ACK:
155  odata = cpu->machine->isa_pic_data.last_int;
156  /* TODO: Actually ack the interrupt? */
157  break;
158 
159  case GT_TIMER_CTRL:
160  if (writeflag == MEM_WRITE) {
161  if (idata & ENTC0) {
162  /* TODO: Don't hardcode this. */
163  d->interrupt_hz = 100;
164  if (d->timer == NULL)
165  d->timer = timer_add(d->interrupt_hz,
166  timer_tick, d);
167  else
169  d->interrupt_hz);
170  }
171  }
172  break;
173 
174  case GT_PCI0_CFG_ADDR:
176  // Hack:
177  if (len == sizeof(uint32_t))
178  {
179  idata = data[0] + (data[1] << 8)
180  + (data[2] << 16) + (data[3] << 24);
181  }
182  }
183  bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
184  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
185  break;
186 
187  case GT_PCI0_CFG_DATA:
189  // Hack:
190  if (len == sizeof(uint32_t))
191  {
192  idata = data[0] + (data[1] << 8)
193  + (data[2] << 16) + (data[3] << 24);
194  }
195  }
196  bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
197  &odata : &idata, len, writeflag);
198  break;
199 
200  default:
201  if (writeflag == MEM_READ) {
202  debug("[ gt: read from addr 0x%x ]\n",
203  (int)relative_addr);
204  } else {
205  debug("[ gt: write to addr 0x%x:", (int)relative_addr);
206  for (i=0; i<len; i++)
207  debug(" %02x", data[i]);
208  debug(" ]\n");
209  }
210  }
211 
212  if (writeflag == MEM_READ)
213  memory_writemax64(cpu, data, len, odata);
214 
215  return 1;
216 }
217 
218 
219 /*
220  * dev_gt_init():
221  *
222  * Initialize a Gallileo PCI controller device. First, the controller itself
223  * is added to the bus, then a pointer to the bus is returned.
224  */
225 struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
226  uint64_t baseaddr, const char *timer_irq_path, const char *isa_irq_path, int type)
227 {
228  struct gt_data *d;
229  uint64_t pci_portbase = 0, pci_membase = 0;
230  uint64_t isa_portbase = 0, isa_membase = 0;
231  uint64_t pci_io_offset = 0, pci_mem_offset = 0;
232  const char *gt_name = "NO";
233 
234  CHECK_ALLOCATION(d = (struct gt_data *) malloc(sizeof(struct gt_data)));
235  memset(d, 0, sizeof(struct gt_data));
236 
237  INTERRUPT_CONNECT(timer_irq_path, d->timer0_irq);
238 
239  switch (type) {
240  case 11:
241  /* Cobalt: */
243  gt_name = "gt64011";
244  pci_io_offset = 0;
245  pci_mem_offset = 0;
246  pci_portbase = 0x10000000ULL;
247  pci_membase = 0x10100000ULL;
248  isa_portbase = 0x10000000ULL;
249  isa_membase = 0x10100000ULL;
250  break;
251  case 120:
252  /* EVBMIPS (Malta): */
254  gt_name = "gt64120";
255  pci_io_offset = 0;
256  pci_mem_offset = 0;
257  pci_portbase = 0x18000000ULL;
258  pci_membase = 0x10000000ULL;
259  isa_portbase = 0x18000000ULL;
260  isa_membase = 0x10000000ULL;
261  break;
262  case 260:
263  /* MVMEPPC (mvme5500): */
265  gt_name = "gt64260";
266  pci_io_offset = 0;
267  pci_mem_offset = 0;
268  pci_portbase = 0x18000000ULL;
269  pci_membase = 0x10000000ULL;
270  isa_portbase = 0x18000000ULL;
271  isa_membase = 0x10000000ULL;
272  break;
273  default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
274  exit(1);
275  }
276 
277 
278  /*
279  * TODO: FIX THESE! Hardcoded numbers = bad.
280  */
281  d->decode[GT_PCI0IOLD_OFS / 8] = pci_portbase >> 21;
282  d->decode[GT_PCI0IOHD_OFS / 8] = 0x40;
283  d->decode[GT_PCI0M0LD_OFS / 8] = 0x80;
284  d->decode[GT_PCI0M0HD_OFS / 8] = 0x3f;
285  d->decode[GT_PCI0M1LD_OFS / 8] = 0xc1;
286  d->decode[GT_PCI0M1HD_OFS / 8] = 0x5e;
290 
292  "TODO_gt_irq", pci_io_offset, pci_mem_offset,
293  pci_portbase, pci_membase, "TODO_pci_irqbase",
294  isa_portbase, isa_membase, isa_irq_path);
295 
296  /*
297  * According to NetBSD/cobalt:
298  * pchb0 at pci0 dev 0 function 0: Galileo GT-64011
299  * System Controller, rev 1
300  */
301  bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, gt_name);
302 
303  memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
304  dev_gt_access, d, DM_DEFAULT, NULL);
305  machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT);
306 
307  return d->pci_data;
308 }
309 
GT_PCI0IOHD_OFS
#define GT_PCI0IOHD_OFS
Definition: gtreg.h:60
data
u_short data
Definition: siireg.h:79
timer_add
struct timer * timer_add(double freq, void(*timer_tick)(struct timer *timer, void *extra), void *extra)
Definition: timer.cc:75
PCI_PRODUCT_GALILEO_GT64011
#define PCI_PRODUCT_GALILEO_GT64011
Definition: dev_gt.cc:55
INTERRUPT_CONNECT
#define INTERRUPT_CONNECT(name, istruct)
Definition: interrupt.h:77
INTERRUPT_ASSERT
#define INTERRUPT_ASSERT(istruct)
Definition: interrupt.h:74
timer
Definition: timer.cc:45
memory
Definition: memory.h:75
debug
#define debug
Definition: dev_adb.cc:57
bus_pci_setaddr
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
GT_PCI0_CFG_ADDR
#define GT_PCI0_CFG_ADDR
Definition: gtreg.h:112
GT_PCI0M0LD_OFS
#define GT_PCI0M0LD_OFS
Definition: gtreg.h:61
gt_data
Definition: dev_gt.cc:60
TICK_SHIFT
#define TICK_SHIFT
Definition: dev_gt.cc:51
gt_data::decode
uint32_t decode[GT_N_DECODE_REGS]
Definition: dev_gt.cc:69
memory_device_register
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
GT_INTR_CAUSE
#define GT_INTR_CAUSE
Definition: gtreg.h:117
bus_pci_data_access
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
dev_gt_access
int dev_gt_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, void *)
MEM_READ
#define MEM_READ
Definition: memory.h:116
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
DM_DEFAULT
#define DM_DEFAULT
Definition: memory.h:130
isa_pic_data::last_int
int last_int
Definition: machine.h:52
gt_data::type
int type
Definition: dev_gt.cc:61
bus_pci_decompose_1
void bus_pci_decompose_1(uint32_t t, int *bus, int *dev, int *func, int *reg)
Definition: bus_pci.cc:76
bus_pci_init
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
gtreg.h
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
dev_gt_init
struct pci_data * dev_gt_init(struct machine *machine, struct memory *mem, uint64_t baseaddr, const char *timer_irq_path, const char *isa_irq_path, int type)
Definition: dev_gt.cc:225
GT_PCI0IOREMAP_OFS
#define GT_PCI0IOREMAP_OFS
Definition: gtreg.h:65
machine_add_tickfunction
void machine_add_tickfunction(struct machine *machine, void(*func)(struct cpu *, void *), void *extra, int clockshift)
Definition: machine.cc:280
gt_data::timer0_irq
struct interrupt timer0_irq
Definition: dev_gt.cc:64
interrupt.h
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
machine::isa_pic_data
struct isa_pic_data isa_pic_data
Definition: machine.h:190
GT_PCI0_CFG_DATA
#define GT_PCI0_CFG_DATA
Definition: gtreg.h:113
PCI_PRODUCT_GALILEO_GT64120
#define PCI_PRODUCT_GALILEO_GT64120
Definition: dev_gt.cc:56
misc.h
GT_PCI0M1LD_OFS
#define GT_PCI0M1LD_OFS
Definition: gtreg.h:63
GT_PCI0M1REMAP_OFS
#define GT_PCI0M1REMAP_OFS
Definition: gtreg.h:67
memory_readmax64
uint64_t memory_readmax64(struct cpu *cpu, unsigned char *buf, int len)
Definition: memory.cc:55
machine.h
machine
Definition: machine.h:97
DEVICE_ACCESS
DEVICE_ACCESS(gt)
Definition: dev_gt.cc:95
timer.h
DEVICE_TICK
DEVICE_TICK(gt)
Definition: dev_gt.cc:87
gt_data::timer
struct timer * timer
Definition: dev_gt.cc:63
GTIC_T0EXP
#define GTIC_T0EXP
Definition: gtreg.h:126
GT_PCI0_INTR_ACK
#define GT_PCI0_INTR_ACK
Definition: gtreg.h:114
gt_data::pci_data
struct pci_data * pci_data
Definition: dev_gt.cc:71
gt_data::pending_timer0_interrupts
int pending_timer0_interrupts
Definition: dev_gt.cc:66
cpu.h
bus_pci.h
EMUL_LITTLE_ENDIAN
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
GT_TIMER_CTRL
#define GT_TIMER_CTRL
Definition: gtreg.h:100
cpu::machine
struct machine * machine
Definition: cpu.h:328
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
PCI_PRODUCT_GALILEO_GT64260
#define PCI_PRODUCT_GALILEO_GT64260
Definition: dev_gt.cc:57
GT_PCI0_CMD_OFS
#define GT_PCI0_CMD_OFS
Definition: gtreg.h:111
DEV_GT_LENGTH
#define DEV_GT_LENGTH
Definition: devices.h:253
gt_data::interrupt_hz
int interrupt_hz
Definition: dev_gt.cc:65
GT_N_DECODE_REGS
#define GT_N_DECODE_REGS
Definition: gtreg.h:69
timer_update_frequency
void timer_update_frequency(struct timer *t, double new_freq)
Definition: timer.cc:132
INTERRUPT_DEASSERT
#define INTERRUPT_DEASSERT(istruct)
Definition: interrupt.h:75
GT_PCI0M0HD_OFS
#define GT_PCI0M0HD_OFS
Definition: gtreg.h:62
GT_PCI0IOLD_OFS
#define GT_PCI0IOLD_OFS
Definition: gtreg.h:59
interrupt
Definition: interrupt.h:36
memory_writemax64
void memory_writemax64(struct cpu *cpu, unsigned char *buf, int len, uint64_t data)
Definition: memory.cc:89
devices.h
ENTC0
#define ENTC0
Definition: gtreg.h:101
cpu
Definition: cpu.h:326
bus_pci_add
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
memory.h
GT_PCI0M1HD_OFS
#define GT_PCI0M1HD_OFS
Definition: gtreg.h:64
GT_PCI0M0REMAP_OFS
#define GT_PCI0M0REMAP_OFS
Definition: gtreg.h:66
CHECK_ALLOCATION
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239

Generated on Tue Mar 24 2020 14:04:48 for GXemul by doxygen 1.8.17