/[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 24 by dpavlin, Mon Oct 8 16:19:56 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.41 2006/03/04 12:38:47 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 44  Line 50 
50  #include "misc.h"  #include "misc.h"
51    
52    
53  #define TICK_STEPS_SHIFT        16  #define TICK_SHIFT              14
54    
55    /*  #define debug fatal  */
56    
57  #define PCI_VENDOR_GALILEO           0x11ab    /* Galileo Technology */  #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /*  GT-64011  */
58  #define PCI_PRODUCT_GALILEO_GT64011  0x4146    /* GT-64011 System Controller */  #define PCI_PRODUCT_GALILEO_GT64120  0x4620    /*  GT-64120  */
59    #define PCI_PRODUCT_GALILEO_GT64260  0x6430    /*  GT-64260  */
60    
61  struct gt_data {  struct gt_data {
         int     reg[8];  
62          int     irqnr;          int     irqnr;
63          int     pciirq;          int     pciirq;
64            int     type;
65    
66          struct pci_data *pci_data;          struct pci_data *pci_data;
67  };  };
# Line 72  void dev_gt_tick(struct cpu *cpu, void * Line 81  void dev_gt_tick(struct cpu *cpu, void *
81  /*  /*
82   *  dev_gt_access():   *  dev_gt_access():
83   */   */
84  int dev_gt_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,  DEVICE_ACCESS(gt)
         unsigned char *data, size_t len, int writeflag, void *extra)  
85  {  {
86          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
87          int i;          int bus, dev, func, reg;
88            size_t i;
89          struct gt_data *d = extra;          struct gt_data *d = extra;
90    
91          idata = memory_readmax64(cpu, data, len);          if (writeflag == MEM_WRITE)
92                    idata = memory_readmax64(cpu, data, len);
93    
94          switch (relative_addr) {          switch (relative_addr) {
95    
96            case 0x48:
97                    switch (d->type) {
98                    case PCI_PRODUCT_GALILEO_GT64120:
99                            /*
100                             *  This is needed for Linux on Malta, according
101                             *  to Alec Voropay.  (TODO: Remove this hack when
102                             *  things have stabilized.)
103                             */
104                            if (writeflag == MEM_READ) {
105                                    odata = 0x18000000 >> 21;
106                                    debug("[ gt: read from 0x48: 0x%08x ]\n",
107                                        (int)odata);
108                            }
109                            break;
110                    default:
111                            fatal("[ gt: access to 0x48? (type %i) ]\n", d->type);
112                    }
113                    break;
114    
115          case 0xc18:          case 0xc18:
116                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
117                          debug("[ gt write to  0xc18: data = 0x%08lx ]\n",                          debug("[ gt: write to  0xc18: 0x%08x ]\n", (int)idata);
                             (long)idata);  
118                          return 1;                          return 1;
119                  } else {                  } else {
120                          odata = 0xffffffffULL;                          odata = 0xffffffffULL;
121                          /*  ???  interrupt something...  */                          /*
122                             *  ???  interrupt something...
123  odata = 0x00000100;     /*  netbsd/cobalt cobalt/machdep.c:cpu_intr()  */                           *
124                             *  TODO: Remove this hack when things have stabilized.
125                             */
126                            odata = 0x00000100;
127                            /*  netbsd/cobalt cobalt/machdep.c:cpu_intr()  */
128    
129  cpu_interrupt_ack(cpu, d->irqnr);                          cpu_interrupt_ack(cpu, d->irqnr);
130    
131                          debug("[ gt read from 0xc18 (data = 0x%08lx) ]\n",                          debug("[ gt: read from 0xc18 (0x%08x) ]\n", (int)odata);
                             (long)odata);  
132                  }                  }
133                  break;                  break;
134    
135            case 0xc34:     /*  GT_PCI0_INTR_ACK  */
136                    odata = cpu->machine->isa_pic_data.last_int;
137                    cpu_interrupt_ack(cpu, 8 + odata);
138                    break;
139    
140          case 0xcf8:     /*  PCI ADDR  */          case 0xcf8:     /*  PCI ADDR  */
141                    if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
142                            fatal("[ gt: TODO: big endian PCI access ]\n");
143                            exit(1);
144                    }
145                    bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
146                    bus_pci_setaddr(cpu, d->pci_data, bus, dev, func, reg);
147                    break;
148    
149          case 0xcfc:     /*  PCI DATA  */          case 0xcfc:     /*  PCI DATA  */
150                  if (writeflag == MEM_WRITE) {                  if (cpu->byte_order != EMUL_LITTLE_ENDIAN) {
151                          bus_pci_access(cpu, mem, relative_addr, &idata,                          fatal("[ gt: TODO: big endian PCI access ]\n");
152                              writeflag, d->pci_data);                          exit(1);
                 } else {  
                         bus_pci_access(cpu, mem, relative_addr, &odata,  
                             writeflag, d->pci_data);  
153                  }                  }
154                    bus_pci_data_access(cpu, d->pci_data, writeflag == MEM_READ?
155                        &odata : &idata, len, writeflag);
156                  break;                  break;
157    
158          default:          default:
159                  if (writeflag==MEM_READ) {                  if (writeflag == MEM_READ) {
160                          debug("[ gt read from addr 0x%x ]\n",                          debug("[ gt: read from addr 0x%x ]\n",
161                              (int)relative_addr);                              (int)relative_addr);
                         odata = d->reg[relative_addr];  
162                  } else {                  } else {
163                          debug("[ gt write to addr 0x%x:", (int)relative_addr);                          debug("[ gt: write to addr 0x%x:", (int)relative_addr);
164                          for (i=0; i<len; i++)                          for (i=0; i<len; i++)
165                                  debug(" %02x", data[i]);                                  debug(" %02x", data[i]);
166                          debug(" ]\n");                          debug(" ]\n");
                         d->reg[relative_addr] = idata;  
167                  }                  }
168          }          }
169    
# Line 131  cpu_interrupt_ack(cpu, d->irqnr); Line 175  cpu_interrupt_ack(cpu, d->irqnr);
175    
176    
177  /*  /*
  *  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)  
 {  
 }  
   
   
 /*  
178   *  dev_gt_init():   *  dev_gt_init():
179   *   *
180   *  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 182  void pci_gt_init(struct machine *machine
182   *  itself.   *  itself.
183   */   */
184  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,  struct pci_data *dev_gt_init(struct machine *machine, struct memory *mem,
185          uint64_t baseaddr, int irq_nr, int pciirq)          uint64_t baseaddr, int irq_nr, int pciirq, int type)
186  {  {
187          struct gt_data *d;          struct gt_data *d;
188            uint64_t pci_portbase = 0, pci_membase = 0;
189            uint64_t isa_portbase = 0, isa_membase = 0;
190            int isa_irqbase = 0, pci_irqbase = 0;
191            uint64_t pci_io_offset = 0, pci_mem_offset = 0;
192            char *gt_name = "NO";
193    
194          d = malloc(sizeof(struct gt_data));          d = malloc(sizeof(struct gt_data));
195          if (d == NULL) {          if (d == NULL) {
# Line 174  struct pci_data *dev_gt_init(struct mach Line 199  struct pci_data *dev_gt_init(struct mach
199          memset(d, 0, sizeof(struct gt_data));          memset(d, 0, sizeof(struct gt_data));
200          d->irqnr    = irq_nr;          d->irqnr    = irq_nr;
201          d->pciirq   = pciirq;          d->pciirq   = pciirq;
202          d->pci_data = bus_pci_init(pciirq);  
203            switch (type) {
204            case 11:
205                    /*  Cobalt:  */
206                    d->type = PCI_PRODUCT_GALILEO_GT64011;
207                    gt_name = "gt64011";
208                    pci_io_offset = 0;
209                    pci_mem_offset = 0;
210                    pci_portbase = 0x10000000ULL;
211                    pci_membase = 0x10100000ULL;
212                    pci_irqbase = 0;
213                    isa_portbase = 0x10000000ULL;
214                    isa_membase = 0x10100000ULL;
215                    isa_irqbase = 8;
216                    break;
217            case 120:
218                    /*  EVBMIPS (Malta):  */
219                    d->type = PCI_PRODUCT_GALILEO_GT64120;
220                    gt_name = "gt64120";
221                    pci_io_offset = 0;
222                    pci_mem_offset = 0;
223                    pci_portbase = 0x18000000ULL;
224                    pci_membase = 0x10000000ULL;
225                    pci_irqbase = 8;
226                    isa_portbase = 0x18000000ULL;
227                    isa_membase = 0x10000000ULL;
228                    isa_irqbase = 8;
229                    break;
230            case 260:
231                    /*  MVMEPPC (mvme5500):  */
232                    d->type = PCI_PRODUCT_GALILEO_GT64260;
233                    gt_name = "gt64260";
234                    pci_io_offset = 0;
235                    pci_mem_offset = 0;
236                    pci_portbase = 0x18000000ULL;
237                    pci_membase = 0x10000000ULL;
238                    pci_irqbase = 8;
239                    isa_portbase = 0x18000000ULL;
240                    isa_membase = 0x10000000ULL;
241                    isa_irqbase = 8;
242                    break;
243            default:fatal("dev_gt_init(): unimplemented GT type (%i).\n", type);
244                    exit(1);
245            }
246    
247            d->pci_data = bus_pci_init(machine,
248                pciirq, pci_io_offset, pci_mem_offset,
249                pci_portbase, pci_membase, pci_irqbase,
250                isa_portbase, isa_membase, isa_irqbase);
251    
252          /*          /*
253           *  According to NetBSD/cobalt:           *  According to NetBSD/cobalt:
254           *  pchb0 at pci0 dev 0 function 0: Galileo GT-64011           *  pchb0 at pci0 dev 0 function 0: Galileo GT-64011
255           *  System Controller, rev 1           *  System Controller, rev 1
256           */           */
257          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);
258    
259          memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,          memory_device_register(mem, "gt", baseaddr, DEV_GT_LENGTH,
260              dev_gt_access, d, MEM_DEFAULT, NULL);              dev_gt_access, d, DM_DEFAULT, NULL);
261          machine_add_tickfunction(machine, dev_gt_tick, d, TICK_STEPS_SHIFT);          machine_add_tickfunction(machine, dev_gt_tick, d, TICK_SHIFT, 0.0);
262    
263          return d->pci_data;          return d->pci_data;
264  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26