/[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 30 by dpavlin, Mon Oct 8 16:20:40 2007 UTC
# 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.43 2006/08/13 08:34:06 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 49  Line 45 
45  #include "memory.h"  #include "memory.h"
46  #include "misc.h"  #include "misc.h"
47    
48    #include "gtreg.h"
49    
50    
51  #define TICK_SHIFT              14  #define TICK_SHIFT              14
52    
# Line 58  Line 56 
56  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */
57  #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */  #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */
58    
59    
60  struct gt_data {  struct gt_data {
61          int     irqnr;          int             timer0_irqnr;
62          int     pciirq;          int             pci_irqbase;
63          int     type;          int             type;
64    
65          struct pci_data *pci_data;          /*  Address decode registers:  */
66            uint32_t        decode[GT_N_DECODE_REGS];
67    
68            struct pci_data *pci_data;
69  };  };
70    
71    
72  /*  DEVICE_TICK(gt)
  *  dev_gt_tick():  
  */  
 void dev_gt_tick(struct cpu *cpu, void *extra)  
73  {  {
74          struct gt_data *gt_data = extra;          struct gt_data *gt_data = extra;
75    
76          cpu_interrupt(cpu, gt_data->irqnr);          /*  TODO: Implement real timer interrupts.  */
77    
78            cpu_interrupt(cpu, gt_data->timer0_irqnr);
79  }  }
80    
81    
 /*  
  *  dev_gt_access():  
  */  
82  DEVICE_ACCESS(gt)  DEVICE_ACCESS(gt)
83  {  {
84          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 93  DEVICE_ACCESS(gt) Line 91  DEVICE_ACCESS(gt)
91    
92          switch (relative_addr) {          switch (relative_addr) {
93    
94          case 0x48:          case GT_PCI0IOLD_OFS:
95                  switch (d->type) {          case GT_PCI0IOHD_OFS:
96                  case PCI_PRODUCT_GALILEO_GT64120:          case GT_PCI0M0LD_OFS:
97                          /*          case GT_PCI0M0HD_OFS:
98                           *  This is needed for Linux on Malta, according          case GT_PCI0M1LD_OFS:
99                           *  to Alec Voropay.  (TODO: Remove this hack when          case GT_PCI0M1HD_OFS:
100                           *  things have stabilized.)          case GT_PCI0IOREMAP_OFS:
101                           */          case GT_PCI0M0REMAP_OFS:
102                          if (writeflag == MEM_READ) {          case GT_PCI0M1REMAP_OFS:
103                                  odata = 0x18000000 >> 21;                  if (writeflag == MEM_READ) {
104                                  debug("[ gt: read from 0x48: 0x%08x ]\n",                          odata = d->decode[relative_addr / 8];
105                                      (int)odata);                          debug("[ gt: read from offset 0x%x: 0x%x ]\n",
106                          }                              (int)relative_addr, (int)odata);
107                          break;                  } else {
108                  default:                          d->decode[relative_addr / 8] = idata;
109                          fatal("[ gt: access to 0x48? (type %i) ]\n", d->type);                          fatal("[ gt: write to offset 0x%x: 0x%x (TODO) ]\n",
110                                (int)relative_addr, (int)idata);
111                  }                  }
112                  break;                  break;
113    
114          case 0xc18:          case GT_PCI0_CMD_OFS:
115                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
116                          debug("[ gt: write to  0xc18: 0x%08x ]\n", (int)idata);                          debug("[ gt: write to GT_PCI0_CMD: 0x%08x (TODO) ]\n",
117                          return 1;                              (int)idata);
118                  } else {                  } else {
119                          odata = 0xffffffffULL;                          debug("[ gt: read from GT_PCI0_CMD (0x%08x) (TODO) ]\n",
120                          /*                              (int)odata);
121                           *  ???  interrupt something...                  }
122                           *                  break;
                          *  TODO: Remove this hack when things have stabilized.  
                          */  
                         odata = 0x00000100;  
                         /*  netbsd/cobalt cobalt/machdep.c:cpu_intr()  */  
123    
124                          cpu_interrupt_ack(cpu, d->irqnr);          case GT_INTR_CAUSE:
125                    if (writeflag == MEM_WRITE) {
126                            debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
127                                (int)idata);
128                            return 1;
129                    } else {
130                            odata = GTIC_T0EXP;
131                            cpu_interrupt_ack(cpu, d->timer0_irqnr);
132    
133                          debug("[ gt: read from 0xc18 (0x%08x) ]\n", (int)odata);                          debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
134                                (int)odata);
135                  }                  }
136                  break;                  break;
137    
138          case 0xc34:     /*  GT_PCI0_INTR_ACK  */          case GT_PCI0_INTR_ACK:
139                  odata = cpu->machine->isa_pic_data.last_int;                  odata = cpu->machine->isa_pic_data.last_int;
140                  cpu_interrupt_ack(cpu, 8 + odata);                  cpu_interrupt_ack(cpu, d->pci_irqbase + odata);
141                  break;                  break;
142    
143          case 0xcf8:     /*  PCI ADDR  */          case GT_PCI0_CFG_ADDR:
144                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
145                          fatal("[ gt: TODO: big endian PCI access ]\n");                          fatal("[ gt: TODO: big endian PCI access ]\n");
146                          exit(1);                          exit(1);
# Line 146  DEVICE_ACCESS(gt) Line 149  DEVICE_ACCESS(gt)
149                  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);                  bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
150                  break;                  break;
151    
152          case 0xcfc:     /*  PCI DATA  */          case GT_PCI0_CFG_DATA:
153                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
154                          fatal("[ gt: TODO: big endian PCI access ]\n");                          fatal("[ gt: TODO: big endian PCI access ]\n");
155                          exit(1);                          exit(1);
# Line 177  DEVICE_ACCESS(gt) Line 180  DEVICE_ACCESS(gt)
180  /*  /*
181   *  dev_gt_init():   *  dev_gt_init():
182   *   *
183   *  Initialize a GT device.  Return a pointer to the pci_data used, so that   *  Initialize a Gallileo PCI controller device. First, the controller itself
184   *  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.  
185   */   */
186  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
187          uint64_t baseaddr, int irq_nr, int pciirq, int type)          uint64_t baseaddr, int irq_nr, int pciirq, int type)
# Line 197  struct pci_data *dev_gt_init(struct mach Line 199  struct pci_data *dev_gt_init(struct mach
199                  exit(1);                  exit(1);
200          }          }
201          memset(d, 0, sizeof(struct gt_data));          memset(d, 0, sizeof(struct gt_data));
202          d->irqnr    = irq_nr;          d->timer0_irqnr = irq_nr;
         d->pciirq   = pciirq;  
203    
204          switch (type) {          switch (type) {
205          case 11:          case 11:
# Line 209  struct pci_data *dev_gt_init(struct mach Line 210  struct pci_data *dev_gt_init(struct mach
210                  pci_mem_offset = 0;                  pci_mem_offset = 0;
211                  pci_portbase = 0x10000000ULL;                  pci_portbase = 0x10000000ULL;
212                  pci_membase = 0x10100000ULL;                  pci_membase = 0x10100000ULL;
213                  pci_irqbase = 0;                  pci_irqbase = 8;
214                  isa_portbase = 0x10000000ULL;                  isa_portbase = 0x10000000ULL;
215                  isa_membase = 0x10100000ULL;                  isa_membase = 0x10100000ULL;
216                  isa_irqbase = 8;                  isa_irqbase = 8;
# Line 244  struct pci_data *dev_gt_init(struct mach Line 245  struct pci_data *dev_gt_init(struct mach
245                  exit(1);                  exit(1);
246          }          }
247    
248    
249            d->pci_irqbase = pci_irqbase;
250    
251            /*
252             *  TODO: FIX THESE! Hardcoded numbers = bad.
253             */
254            d->decode[GT_PCI0IOLD_OFS / 8] = pci_portbase >> 21;
255            d->decode[GT_PCI0IOHD_OFS / 8] = 0x40;
256            d->decode[GT_PCI0M0LD_OFS / 8] = 0x80;
257            d->decode[GT_PCI0M0HD_OFS / 8] = 0x3f;
258            d->decode[GT_PCI0M1LD_OFS / 8] = 0xc1;
259            d->decode[GT_PCI0M1HD_OFS / 8] = 0x5e;
260            d->decode[GT_PCI0IOREMAP_OFS / 8] = d->decode[GT_PCI0IOLD_OFS / 8];
261            d->decode[GT_PCI0M0REMAP_OFS / 8] = d->decode[GT_PCI0M0LD_OFS / 8];
262            d->decode[GT_PCI0M1REMAP_OFS / 8] = d->decode[GT_PCI0M1LD_OFS / 8];
263    
264          d->pci_data = bus_pci_init(machine,          d->pci_data = bus_pci_init(machine,
265              pciirq, pci_io_offset, pci_mem_offset,              pciirq, pci_io_offset, pci_mem_offset,
266              pci_portbase, pci_membase, pci_irqbase,              pci_portbase, pci_membase, pci_irqbase,

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

  ViewVC Help
Powered by ViewVC 1.1.26