/[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 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  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.21 2005/03/18 23:20:52 debug Exp $   *  $Id: dev_gt.c,v 1.42 2006/07/21 16:55:41 debug Exp $
29   *     *  
30   *  The "gt" device used in Cobalt machines.   *  Galileo Technology GT-64xxx PCI controller.
31   *   *
32   *  TODO:  This more or less just a dummy device, so far.   *      GT-64011        Used in Cobalt machines.
33     *      GT-64120        Used in evbmips machines (Malta).
34     *      GT-64260        Used in mvmeppc machines.
35     *
36     *  TODO: This more or less just a dummy device, so far. It happens to work
37     *        with some NetBSD ports in some cases, and perhaps with Linux too,
38     *        but it is not really working for anything else.
39   */   */
40    
41  #include <stdio.h>  #include <stdio.h>
# Line 43  Line 49 
49  #include "memory.h"  #include "memory.h"
50  #include "misc.h"  #include "misc.h"
51    
52    #include "gtreg.h"
53    
54    
55    #define TICK_SHIFT              14
56    
57    /*  #define debug fatal  */
58    
59  #define TICK_STEPS_SHIFT        16  #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /*  GT-64011  */
60    #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */
61    #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */
62    
 #define PCI_VENDOR_GALILEO           0x11ab    /* Galileo Technology */  
 #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /* GT-64011 System Controller */  
63    
64  struct gt_data {  struct gt_data {
65          int     reg[8];          int             timer0_irqnr;
66          int     irqnr;          int             pci_irqbase;
67          int     pciirq;          int             type;
68    
69          struct pci_data *pci_data;          uint32_t        pci0_iold;      /*  I/O Low Decode address  */
70            uint32_t        pci0_iohd;      /*  I/O High Decode address  */
71    
72            struct pci_data *pci_data;
73  };  };
74    
75    
76  /*  DEVICE_TICK(gt)
  *  dev_gt_tick():  
  */  
 void dev_gt_tick(struct cpu *cpu, void *extra)  
77  {  {
78          struct gt_data *gt_data = extra;          struct gt_data *gt_data = extra;
79    
80          cpu_interrupt(cpu, gt_data->irqnr);          /*  TODO: Implement real timer interrupts.  */
81    
82            cpu_interrupt(cpu, gt_data->timer0_irqnr);
83  }  }
84    
85    
86  /*  DEVICE_ACCESS(gt)
  *  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 *extra)  
87  {  {
88          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
89          int i;          int bus, dev, func, reg;
90            size_t i;
91          struct gt_data *d = extra;          struct gt_data *d = extra;
92    
93          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
94                    idata = memory_readmax64(cpu, data, len);
95    
96          switch (relative_addr) {          switch (relative_addr) {
97          case 0xc18:  
98            case GT_PCI0IOLD_OFS:
99                    if (writeflag == MEM_READ) {
100                            odata = d->pci0_iold;
101                    } else {
102                            fatal("[ gt: write to GT_PCI0IOLD_OFS: 0x%x (TODO) ]\n",
103                                (int)idata);
104                    }
105                    break;
106    
107            case GT_PCI0IOHD_OFS:
108                    if (writeflag == MEM_READ) {
109                            odata = d->pci0_iohd;
110                    } else {
111                            fatal("[ gt: write to GT_PCI0IOHD_OFS: 0x%x (TODO) ]\n",
112                                (int)idata);
113                    }
114                    break;
115    
116            case GT_PCI0IOREMAP_OFS:
117                    /*  TODO: Same as GT_PCI0IOLD_OFS?  */
118                    if (writeflag == MEM_READ) {
119                            odata = d->pci0_iold;
120                    } else {
121                            debug("[ gt: write to GT_PCI0IOREMAP_OFS: 0x%x "
122                                "(TODO) ]\n", (int)idata);
123                    }
124                    break;
125    
126            case GT_INTR_CAUSE:
127                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
128                          debug("[ gt write to  0xc18: data = 0x%08lx ]\n",                          debug("[ gt: write to GT_INTR_CAUSE: 0x%08x ]\n",
129                              (long)idata);                              (int)idata);
130                          return 1;                          return 1;
131                  } else {                  } else {
132                          odata = 0xffffffffULL;                          odata = GTIC_T0EXP;
133                          /*  ???  interrupt something...  */                          cpu_interrupt_ack(cpu, d->timer0_irqnr);
134    
135  odata = 0x00000100;     /*  netbsd/cobalt cobalt/machdep.c:cpu_intr()  */                          debug("[ gt: read from GT_INTR_CAUSE (0x%08x) ]\n",
136                                (int)odata);
137                    }
138                    break;
139    
140  cpu_interrupt_ack(cpu, d->irqnr);          case GT_PCI0_INTR_ACK:
141                    odata = cpu->machine->isa_pic_data.last_int;
142                    cpu_interrupt_ack(cpu, d->pci_irqbase + odata);
143                    break;
144    
145                          debug("[ gt read from 0xc18 (data = 0x%08lx) ]\n",          case GT_PCI0_CFG_ADDR:
146                              (long)odata);                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
147                            fatal("[ gt: TODO: big endian PCI access ]\n");
148                            exit(1);
149                  }                  }
150                    bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
151                    bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
152                  break;                  break;
153          case 0xcf8:     /*  PCI ADDR  */  
154          case 0xcfc:     /*  PCI DATA  */          case GT_PCI0_CFG_DATA:
155                  if (writeflag == MEM_WRITE) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
156                          bus_pci_access(cpu, mem, relative_addr, &idata,                          fatal("[ gt: TODO: big endian PCI access ]\n");
157                              writeflag, d->pci_data);                          exit(1);
                 } else {  
                         bus_pci_access(cpu, mem, relative_addr, &odata,  
                             writeflag, d->pci_data);  
158                  }                  }
159                    bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
160                        &odata : &idata, len, writeflag);
161                  break;                  break;
162    
163          default:          default:
164                  if (writeflag==MEM_READ) {                  if (writeflag == MEM_READ) {
165                          debug("[ gt read from addr 0x%x ]\n",                          debug("[ gt: read from addr 0x%x ]\n",
166                              (int)relative_addr);                              (int)relative_addr);
                         odata = d->reg[relative_addr];  
167                  } else {                  } else {
168                          debug("[ gt write to addr 0x%x:", (int)relative_addr);                          debug("[ gt: write to addr 0x%x:", (int)relative_addr);
169                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
170                                  debug(" %02x", data[i]);                                  debug(" %02x", data[i]);
171                          debug(" ]\n");                          debug(" ]\n");
                         d->reg[relative_addr] = idata;  
172                  }                  }
173          }          }
174    
# Line 131  cpu_interrupt_ack(cpu, d->irqnr); Line 180  cpu_interrupt_ack(cpu, d->irqnr);
180    
181    
182  /*  /*
  *  pci_gt_rr():  
  */  
 uint32_t pci_gt_rr(int reg)  
 {  
         switch (reg) {  
         case 0x00:  
                 return PCI_VENDOR_GALILEO + (PCI_PRODUCT_GALILEO_GT64011 << 16);  
         case 0x08:  
                 return 0x01;    /*  Revision 1  */  
         default:  
                 return 0;  
         }  
 }  
   
   
 /*  
  *  pci_gt_init():  
  */  
 void pci_gt_init(struct machine *machine, struct memory *mem)  
 {  
 }  
   
   
 /*  
183   *  dev_gt_init():   *  dev_gt_init():
184   *   *
185   *  Initialize a GT device.  Return a pointer to the pci_data used, so that   *  Initialize a GT device.  Return a pointer to the pci_data used, so that
# Line 162  void pci_gt_init(struct machine *machine Line 187  void pci_gt_init(struct machine *machine
187   *  itself.   *  itself.
188   */   */
189  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
190          uint64_t baseaddr, int irq_nr, int pciirq)          uint64_t baseaddr, int irq_nr, int pciirq, int type)
191  {  {
192          struct gt_data *d;          struct gt_data *d;
193            uint64_t pci_portbase = 0, pci_membase = 0;
194            uint64_t isa_portbase = 0, isa_membase = 0;
195            int isa_irqbase = 0, pci_irqbase = 0;
196            uint64_t pci_io_offset = 0, pci_mem_offset = 0;
197            char *gt_name = "NO";
198    
199          d = malloc(sizeof(struct gt_data));          d = malloc(sizeof(struct gt_data));
200          if (d == NULL) {          if (d == NULL) {
# Line 172  struct pci_data *dev_gt_init(struct mach Line 202  struct pci_data *dev_gt_init(struct mach
202                  exit(1);                  exit(1);
203          }          }
204          memset(d, 0, sizeof(struct gt_data));          memset(d, 0, sizeof(struct gt_data));
205          d->irqnr    = irq_nr;          d->timer0_irqnr = irq_nr;
206          d->pciirq   = pciirq;  
207          d->pci_data = bus_pci_init(pciirq);          switch (type) {
208            case 11:
209                    /*  Cobalt:  */
210                    d->type = PCI_PRODUCT_GALILEO_GT64011;
211                    gt_name = "gt64011";
212                    pci_io_offset = 0;
213                    pci_mem_offset = 0;
214                    pci_portbase = 0x10000000ULL;
215                    pci_membase = 0x10100000ULL;
216                    pci_irqbase = 8;
217                    isa_portbase = 0x10000000ULL;
218                    isa_membase = 0x10100000ULL;
219                    isa_irqbase = 8;
220                    break;
221            case 120:
222                    /*  EVBMIPS (Malta):  */
223                    d->type = PCI_PRODUCT_GALILEO_GT64120;
224                    gt_name = "gt64120";
225                    pci_io_offset = 0;
226                    pci_mem_offset = 0;
227                    pci_portbase = 0x18000000ULL;
228                    pci_membase = 0x10000000ULL;
229                    pci_irqbase = 8;
230                    isa_portbase = 0x18000000ULL;
231                    isa_membase = 0x10000000ULL;
232                    isa_irqbase = 8;
233                    break;
234            case 260:
235                    /*  MVMEPPC (mvme5500):  */
236                    d->type = PCI_PRODUCT_GALILEO_GT64260;
237                    gt_name = "gt64260";
238                    pci_io_offset = 0;
239                    pci_mem_offset = 0;
240                    pci_portbase = 0x18000000ULL;
241                    pci_membase = 0x10000000ULL;
242                    pci_irqbase = 8;
243                    isa_portbase = 0x18000000ULL;
244                    isa_membase = 0x10000000ULL;
245                    isa_irqbase = 8;
246                    break;
247            default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
248                    exit(1);
249            }
250    
251            d->pci_irqbase = pci_irqbase;
252            d->pci0_iold = pci_portbase >> 21;
253            d->pci0_iohd = 0x0000000f;      /*  TODO?  */
254    
255            d->pci_data = bus_pci_init(machine,
256                pciirq, pci_io_offset, pci_mem_offset,
257                pci_portbase, pci_membase, pci_irqbase,
258                isa_portbase, isa_membase, isa_irqbase);
259    
260          /*          /*
261           *  According to NetBSD/cobalt:           *  According to NetBSD/cobalt:
262           *  pchb0 at pci0 dev 0 function 0: Galileo GT-64011           *  pchb0 at pci0 dev 0 function 0: Galileo GT-64011
263           *  System Controller, rev 1           *  System Controller, rev 1
264           */           */
265          bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, pci_gt_init, pci_gt_rr);          bus_pci_add(machine, d->pci_data, mem, 0, 0, 0, gt_name);
266    
267          memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,          memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
268              dev_gt_access, d, MEM_DEFAULT, NULL);              dev_gt_access, d, DM_DEFAULT, NULL);
269          machine_add_tickfunction(machine, dev_gt_tick, d, TICK_STEPS_SHIFT);          machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT, 0.0);
270    
271          return d->pci_data;          return d->pci_data;
272  }  }

Legend:
Removed from v.4  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26