/[gxemul]/trunk/src/devices/dev_gt.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/devices/dev_gt.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_gt.c,v 1.41 2006/03/04 12:38:47 debug Exp $   *  $Id: dev_gt.c,v 1.49 2007/01/05 16:50:08 debug Exp $
29   *     *  
30   *  Galileo Technology GT-64xxx PCI controller.   *  Galileo Technology GT-64xxx PCI controller.
31   *   *
32   *      GT-64011        Used in Cobalt machines.   *      GT-64011        Used in Cobalt machines.
33   *      GT-64120        Used in evbmips machines (Malta).   *      GT-64120        Used in evbmips machines (Malta).
34   *      GT-64260        Used in mvmeppc machines.   *      GT-64260        Used in mvmeppc machines.
  *  
  *  TODO: This more or less just a dummy device, so far. It happens to work  
  *        with some NetBSD ports in some cases, and perhaps with Linux too,  
  *        but it is not really working for anything else.  
35   */   */
36    
37  #include <stdio.h>  #include <stdio.h>
# Line 45  Line 41 
41  #include "bus_pci.h"  #include "bus_pci.h"
42  #include "cpu.h"  #include "cpu.h"
43  #include "devices.h"  #include "devices.h"
44    #include "interrupt.h"
45  #include "machine.h"  #include "machine.h"
46  #include "memory.h"  #include "memory.h"
47  #include "misc.h"  #include "misc.h"
48    #include "timer.h"
49    
50    #include "gtreg.h"
51    
52    
53  #define TICK_SHIFT              14  #define TICK_SHIFT              14
# Line 58  Line 58 
58  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */
59  #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */  #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */
60    
61    
62  struct gt_data {  struct gt_data {
63          int     irqnr;          int             type;
64          int     pciirq;  
65          int     type;          struct timer    *timer;
66            struct interrupt timer0_irq;
67            int             interrupt_hz;
68            int             pending_timer0_interrupts;
69    
70          struct pci_data *pci_data;          /*  Address decode registers:  */
71            uint32_t        decode[GT_N_DECODE_REGS];
72    
73            struct pci_data *pci_data;
74  };  };
75    
76    
77  /*  /*
78   *  dev_gt_tick():   *  timer_tick():
79     *
80     *  Called d->interrupt_hz times per (real-world) second.
81   */   */
82  void dev_gt_tick(struct cpu *cpu, void *extra)  static void timer_tick(struct timer *timer, void *extra)
83    {
84            struct gt_data *d = (struct gt_data *) extra;
85            d->pending_timer0_interrupts ++;
86    }
87    
88    
89    DEVICE_TICK(gt)
90  {  {
91          struct gt_data *gt_data = extra;          struct gt_data *d = (struct gt_data *) extra;
92    
93          cpu_interrupt(cpu, gt_data->irqnr);          if (d->pending_timer0_interrupts > 0)
94                    INTERRUPT_ASSERT(d->timer0_irq);
95  }  }
96    
97    
 /*  
  *  dev_gt_access():  
  */  
98  DEVICE_ACCESS(gt)  DEVICE_ACCESS(gt)
99  {  {
100          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 93  DEVICE_ACCESS(gt) Line 107  DEVICE_ACCESS(gt)
107    
108          switch (relative_addr) {          switch (relative_addr) {
109    
110          case 0x48:          case GT_PCI0IOLD_OFS:
111                  switch (d->type) {          case GT_PCI0IOHD_OFS:
112                  case PCI_PRODUCT_GALILEO_GT64120:          case GT_PCI0M0LD_OFS:
113                          /*          case GT_PCI0M0HD_OFS:
114                           *  This is needed for Linux on Malta, according          case GT_PCI0M1LD_OFS:
115                           *  to Alec Voropay.  (TODO: Remove this hack when          case GT_PCI0M1HD_OFS:
116                           *  things have stabilized.)          case GT_PCI0IOREMAP_OFS:
117                           */          case GT_PCI0M0REMAP_OFS:
118                          if (writeflag == MEM_READ) {          case GT_PCI0M1REMAP_OFS:
119                                  odata = 0x18000000 >> 21;                  if (writeflag == MEM_READ) {
120                                  debug("[ gt: read from 0x48: 0x%08x ]\n",                          odata = d->decode[relative_addr / 8];
121                                      (int)odata);                          debug("[ gt: read from offset 0x%x: 0x%x ]\n",
122                          }                              (int)relative_addr, (int)odata);
123                          break;                  } else {
124                  default:                          d->decode[relative_addr / 8] = idata;
125                          fatal("[ gt: access to 0x48? (type %i) ]\n", d->type);                          fatal("[ gt: write to offset 0x%x: 0x%x (TODO) ]\n",
126                                (int)relative_addr, (int)idata);
127                  }                  }
128                  break;                  break;
129    
130          case 0xc18:          case GT_PCI0_CMD_OFS:
131                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
132                          debug("[ gt: write to  0xc18: 0x%08x ]\n", (int)idata);                          debug("[ gt: write to GT_PCI0_CMD: 0x%08x (TODO) ]\n",
133                                (int)idata);
134                    } else {
135                            debug("[ gt: read from GT_PCI0_CMD (0x%08x) (TODO) ]\n",
136                                (int)odata);
137                    }
138                    break;
139    
140            case GT_INTR_CAUSE:
141                    if (writeflag == MEM_WRITE) {
142                            debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
143                                (int)idata);
144                          return 1;                          return 1;
145                  } else {                  } else {
146                          odata = 0xffffffffULL;                          odata = GTIC_T0EXP;
147                          /*                          INTERRUPT_DEASSERT(d->timer0_irq);
                          *  ???  interrupt something...  
                          *  
                          *  TODO: Remove this hack when things have stabilized.  
                          */  
                         odata = 0x00000100;  
                         /*  netbsd/cobalt cobalt/machdep.c:cpu_intr()  */  
148    
149                          cpu_interrupt_ack(cpu, d->irqnr);                          if (d->pending_timer0_interrupts > 0)
150                                    d->pending_timer0_interrupts --;
151    
152                          debug("[ gt: read from 0xc18 (0x%08x) ]\n", (int)odata);                          debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
153                                (int)odata);
154                  }                  }
155                  break;                  break;
156    
157          case 0xc34:     /*  GT_PCI0_INTR_ACK  */          case GT_PCI0_INTR_ACK:
158                  odata = cpu->machine->isa_pic_data.last_int;                  odata = cpu->machine->isa_pic_data.last_int;
159                  cpu_interrupt_ack(cpu, 8 + odata);  
160    fatal("TODO: GT_PCI0_INTR_ACK\n");
161    
162    //              cpu_interrupt_ack(cpu, d->pci_irqbase + odata);
163                  break;                  break;
164    
165          case 0xcf8:     /*  PCI ADDR  */          case GT_TIMER_CTRL:
166                    if (writeflag == MEM_WRITE) {
167                            if (idata & ENTC0) {
168                                    /*  TODO: Don't hardcode this.  */
169                                    d->interrupt_hz = 100;
170                                    if (d->timer == NULL)
171                                            d->timer = timer_add(d->interrupt_hz,
172                                                timer_tick, d);
173                                    else
174                                            timer_update_frequency(d->timer,
175                                                d->interrupt_hz);
176                            }
177                    }
178                    break;
179    
180            case GT_PCI0_CFG_ADDR:
181                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
182                          fatal("[ gt: TODO: big endian PCI access ]\n");                          fatal("[ gt: TODO: big endian PCI access ]\n");
183                          exit(1);                          exit(1);
# Line 146  DEVICE_ACCESS(gt) Line 186  DEVICE_ACCESS(gt)
186                  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);                  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
187                  break;                  break;
188    
189          case 0xcfc:     /*  PCI DATA  */          case GT_PCI0_CFG_DATA:
190                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
191                          fatal("[ gt: TODO: big endian PCI access ]\n");                          fatal("[ gt: TODO: big endian PCI access ]\n");
192                          exit(1);                          exit(1);
# Line 177  DEVICE_ACCESS(gt) Line 217  DEVICE_ACCESS(gt)
217  /*  /*
218   *  dev_gt_init():   *  dev_gt_init():
219   *   *
220   *  Initialize a GT device.  Return a pointer to the pci_data used, so that   *  Initialize a Gallileo PCI controller device. First, the controller itself
221   *  the caller may add PCI devices.  First, however, we add the GT device   *  is added to the bus, then a pointer to the bus is returned.
  *  itself.  
222   */   */
223  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
224          uint64_t baseaddr, int irq_nr, int pciirq, int type)          uint64_t baseaddr, char *timer_irq_path, char *isa_irq_path, int type)
225  {  {
226          struct gt_data *d;          struct gt_data *d;
227          uint64_t pci_portbase = 0, pci_membase = 0;          uint64_t pci_portbase = 0, pci_membase = 0;
228          uint64_t isa_portbase = 0, isa_membase = 0;          uint64_t isa_portbase = 0, isa_membase = 0;
         int isa_irqbase = 0, pci_irqbase = 0;  
229          uint64_t pci_io_offset = 0, pci_mem_offset = 0;          uint64_t pci_io_offset = 0, pci_mem_offset = 0;
230          char *gt_name = "NO";          char *gt_name = "NO";
231    
# Line 197  struct pci_data *dev_gt_init(struct mach Line 235  struct pci_data *dev_gt_init(struct mach
235                  exit(1);                  exit(1);
236          }          }
237          memset(d, 0, sizeof(struct gt_data));          memset(d, 0, sizeof(struct gt_data));
238          d->irqnr    = irq_nr;  
239          d->pciirq   = pciirq;          INTERRUPT_CONNECT(timer_irq_path, d->timer0_irq);
240    
241          switch (type) {          switch (type) {
242          case 11:          case 11:
# Line 209  struct pci_data *dev_gt_init(struct mach Line 247  struct pci_data *dev_gt_init(struct mach
247                  pci_mem_offset = 0;                  pci_mem_offset = 0;
248                  pci_portbase = 0x10000000ULL;                  pci_portbase = 0x10000000ULL;
249                  pci_membase = 0x10100000ULL;                  pci_membase = 0x10100000ULL;
                 pci_irqbase = 0;  
250                  isa_portbase = 0x10000000ULL;                  isa_portbase = 0x10000000ULL;
251                  isa_membase = 0x10100000ULL;                  isa_membase = 0x10100000ULL;
                 isa_irqbase = 8;  
252                  break;                  break;
253          case 120:          case 120:
254                  /*  EVBMIPS (Malta):  */                  /*  EVBMIPS (Malta):  */
# Line 222  struct pci_data *dev_gt_init(struct mach Line 258  struct pci_data *dev_gt_init(struct mach
258                  pci_mem_offset = 0;                  pci_mem_offset = 0;
259                  pci_portbase = 0x18000000ULL;                  pci_portbase = 0x18000000ULL;
260                  pci_membase = 0x10000000ULL;                  pci_membase = 0x10000000ULL;
                 pci_irqbase = 8;  
261                  isa_portbase = 0x18000000ULL;                  isa_portbase = 0x18000000ULL;
262                  isa_membase = 0x10000000ULL;                  isa_membase = 0x10000000ULL;
                 isa_irqbase = 8;  
263                  break;                  break;
264          case 260:          case 260:
265                  /*  MVMEPPC (mvme5500):  */                  /*  MVMEPPC (mvme5500):  */
# Line 235  struct pci_data *dev_gt_init(struct mach Line 269  struct pci_data *dev_gt_init(struct mach
269                  pci_mem_offset = 0;                  pci_mem_offset = 0;
270                  pci_portbase = 0x18000000ULL;                  pci_portbase = 0x18000000ULL;
271                  pci_membase = 0x10000000ULL;                  pci_membase = 0x10000000ULL;
                 pci_irqbase = 8;  
272                  isa_portbase = 0x18000000ULL;                  isa_portbase = 0x18000000ULL;
273                  isa_membase = 0x10000000ULL;                  isa_membase = 0x10000000ULL;
                 isa_irqbase = 8;  
274                  break;                  break;
275          default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);          default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
276                  exit(1);                  exit(1);
277          }          }
278    
279    
280            /*
281             *  TODO: FIX THESE! Hardcoded numbers = bad.
282             */
283            d->decode[GT_PCI0IOLD_OFS / 8] = pci_portbase >> 21;
284            d->decode[GT_PCI0IOHD_OFS / 8] = 0x40;
285            d->decode[GT_PCI0M0LD_OFS / 8] = 0x80;
286            d->decode[GT_PCI0M0HD_OFS / 8] = 0x3f;
287            d->decode[GT_PCI0M1LD_OFS / 8] = 0xc1;
288            d->decode[GT_PCI0M1HD_OFS / 8] = 0x5e;
289            d->decode[GT_PCI0IOREMAP_OFS / 8] = d->decode[GT_PCI0IOLD_OFS / 8];
290            d->decode[GT_PCI0M0REMAP_OFS / 8] = d->decode[GT_PCI0M0LD_OFS / 8];
291            d->decode[GT_PCI0M1REMAP_OFS / 8] = d->decode[GT_PCI0M1LD_OFS / 8];
292    
293          d->pci_data = bus_pci_init(machine,          d->pci_data = bus_pci_init(machine,
294              pciirq, pci_io_offset, pci_mem_offset,              "TODO irq stuff!", pci_io_offset, pci_mem_offset,
295              pci_portbase, pci_membase, pci_irqbase,              pci_portbase, pci_membase, "TODO: pci_irqbase",
296              isa_portbase, isa_membase, isa_irqbase);              isa_portbase, isa_membase, isa_irq_path);
297    
298          /*          /*
299           *  According to NetBSD/cobalt:           *  According to NetBSD/cobalt:

Legend:
Removed from v.24  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26