/[gxemul]/trunk/src/devices/dev_footbridge.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_footbridge.c

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

revision 19 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: dev_footbridge.c,v 1.26 2005/10/26 14:37:04 debug Exp $   *  $Id: dev_footbridge.c,v 1.36 2005/11/21 09:17:26 debug Exp $
29   *   *
30   *  Footbridge. Used in Netwinder and Cats.   *  Footbridge. Used in Netwinder and Cats.
31   *   *
32   *  TODO: Most things. For example:   *  TODO:
  *  
  *      o)  Fix the timer TODO (see below).  
  *  
33   *      o)  Add actual support for the fcom serial port.   *      o)  Add actual support for the fcom serial port.
  *  
34   *      o)  FIQs.   *      o)  FIQs.
  *  
  *      o)  ..  
35   */   */
36    
37  #include <stdio.h>  #include <stdio.h>
# Line 107  void dev_footbridge_tick(struct cpu *cpu Line 101  void dev_footbridge_tick(struct cpu *cpu
101  /*  /*
102   *  dev_footbridge_isa_access():   *  dev_footbridge_isa_access():
103   *   *
104   *  NetBSD seems to read 0x79000000 to find out which ISA interrupt occurred,   *  Reading the byte at 0x79000000 is a quicker way to figure out which ISA
105   *  a quicker way than dealing with legacy 0x20/0xa0 ISA ports.   *  interrupt has occurred (and acknowledging it at the same time), than
106     *  dealing with the legacy 0x20/0xa0 ISA ports.
107   */   */
108  int dev_footbridge_isa_access(struct cpu *cpu, struct memory *mem,  int dev_footbridge_isa_access(struct cpu *cpu, struct memory *mem,
109          uint64_t relative_addr, unsigned char *data, size_t len,          uint64_t relative_addr, unsigned char *data, size_t len,
# Line 123  int dev_footbridge_isa_access(struct cpu Line 118  int dev_footbridge_isa_access(struct cpu
118                  fatal("[ footbridge_isa: WARNING/TODO: write! ]\n");                  fatal("[ footbridge_isa: WARNING/TODO: write! ]\n");
119          }          }
120    
121          /*          x = cpu->machine->isa_pic_data.last_int;
122           *  NetBSD seems to want a value of 0x20 + x, where x is the highest          if (x == 0)
123           *  priority ISA interrupt which is currently asserted and not masked.                  cpu_interrupt_ack(cpu, 32 + x);
124           */  
125            if (x < 8)
126          for (x=0; x<16; x++) {                  odata = cpu->machine->isa_pic_data.pic1->irq_base + x;
127                  if (x == 2)          else
128                          continue;                  odata = cpu->machine->isa_pic_data.pic2->irq_base + x - 8;
                 if (x < 8 && (cpu->machine->isa_pic_data.pic1->irr &  
                     ~cpu->machine->isa_pic_data.pic1->ier &  
                     (1 << x)))  
                         break;  
                 if (x >= 8 && (cpu->machine->isa_pic_data.pic2->irr &  
                     ~cpu->machine->isa_pic_data.pic2->ier &  
                     (1 << (x&7))))  
                         break;  
         }  
   
         if (x == 16)  
                 fatal("_\n_  SPORADIC but INVALID ISA interrupt\n_\n");  
   
         odata = 0x20 + (x & 15);  
129    
130          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
131                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
# Line 196  int dev_footbridge_pci_access(struct cpu Line 177  int dev_footbridge_pci_access(struct cpu
177          pci_word = relative_addr & 0x00ffffff;          pci_word = relative_addr & 0x00ffffff;
178    
179          res = bus_pci_access(cpu, mem, BUS_PCI_ADDR,          res = bus_pci_access(cpu, mem, BUS_PCI_ADDR,
180              &pci_word, MEM_WRITE, d->pcibus);              &pci_word, sizeof(uint32_t), MEM_WRITE, d->pcibus);
181          if (writeflag == MEM_READ) {          if (writeflag == MEM_READ) {
182                  res = bus_pci_access(cpu, mem, BUS_PCI_DATA,                  res = bus_pci_access(cpu, mem, BUS_PCI_DATA,
183                      &pci_word, MEM_READ, d->pcibus);                      &pci_word, len, MEM_READ, d->pcibus);
184                  odata = pci_word;                  odata = pci_word;
185          } else {          } else {
186                  pci_word = idata;                  pci_word = idata;
187                  res = bus_pci_access(cpu, mem, BUS_PCI_DATA,                  res = bus_pci_access(cpu, mem, BUS_PCI_DATA,
188                      &pci_word, MEM_WRITE, d->pcibus);                      &pci_word, len, MEM_WRITE, d->pcibus);
189          }          }
190    
191          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
# Line 245  int dev_footbridge_access(struct cpu *cp Line 226  int dev_footbridge_access(struct cpu *cp
226                  odata = 0x1065;  /*  DC21285_DEVICE_ID  */                  odata = 0x1065;  /*  DC21285_DEVICE_ID  */
227                  break;                  break;
228    
229            case 0x04:
230            case 0x0c:
231            case 0x10:
232            case 0x14:
233            case 0x18:
234                    /*  TODO. Written to by Linux.  */
235                    break;
236    
237          case REVISION:          case REVISION:
238                  odata = 3;  /*  footbridge revision number  */                  odata = 3;  /*  footbridge revision number  */
239                  break;                  break;
240    
241            case PCI_ADDRESS_EXTENSION:
242                    /*  TODO: Written to by Linux.  */
243                    if (writeflag == MEM_WRITE && idata != 0)
244                            fatal("[ footbridge: TODO: write to PCI_ADDRESS_"
245                                "EXTENSION: 0x%llx ]\n", (long long)idata);
246                    break;
247    
248          case UART_DATA:          case UART_DATA:
249                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
250                          console_putchar(d->console_handle, idata);                          console_putchar(d->console_handle, idata);
# Line 349  int dev_footbridge_access(struct cpu *cp Line 345  int dev_footbridge_access(struct cpu *cp
345          case TIMER_1_VALUE:          case TIMER_1_VALUE:
346                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
347                          /*                          /*
348                           *  TODO: This is INCORRECT! but speeds up NetBSD                           *  NOTE/TODO: This is INCORRECT but speeds up NetBSD
349                           *  and OpenBSD boot sequences. A better solution                           *  and OpenBSD boot sequences: if the timer is polled
350                           *  would be to only call dev_footbridge_tick() if                           *  "very often" (such as during bootup), then this
351                           *  the timer is polled "very often" (such as during                           *  causes the timers to expire quickly.
                          *  bootup), but not during normal operation.  
352                           */                           */
353                          d->timer_being_read = 1;                          d->timer_being_read = 1;
354                          d->timer_poll_mode ++;                          d->timer_poll_mode ++;
355                          if (d->timer_poll_mode > TIMER_POLL_THRESHOLD)                          if (d->timer_poll_mode >= TIMER_POLL_THRESHOLD) {
356                                    d->timer_poll_mode = TIMER_POLL_THRESHOLD;
357                                  dev_footbridge_tick(cpu, d);                                  dev_footbridge_tick(cpu, d);
358                                    dev_footbridge_tick(cpu, d);
359                                    dev_footbridge_tick(cpu, d);
360                            }
361                          odata = d->timer_value[timer_nr];                          odata = d->timer_value[timer_nr];
362                          d->timer_being_read = 0;                          d->timer_being_read = 0;
363                  } else                  } else
# Line 428  int devinit_footbridge(struct devinit *d Line 427  int devinit_footbridge(struct devinit *d
427          /*  DC21285 register access:  */          /*  DC21285 register access:  */
428          memory_device_register(devinit->machine->memory, devinit->name,          memory_device_register(devinit->machine->memory, devinit->name,
429              devinit->addr, DEV_FOOTBRIDGE_LENGTH,              devinit->addr, DEV_FOOTBRIDGE_LENGTH,
430              dev_footbridge_access, d, MEM_DEFAULT, NULL);              dev_footbridge_access, d, DM_DEFAULT, NULL);
431    
432          /*  ISA interrupt status word:  */          /*  ISA interrupt status/acknowledgement:  */
433          memory_device_register(devinit->machine->memory, "footbridge_isa",          memory_device_register(devinit->machine->memory, "footbridge_isa",
434              0x79000000, 8, dev_footbridge_isa_access, d, MEM_DEFAULT, NULL);              0x79000000, 8, dev_footbridge_isa_access, d, DM_DEFAULT, NULL);
435    
436          /*  The "fcom" console:  */          /*  The "fcom" console:  */
437          d->console_handle = console_start_slave(devinit->machine, "fcom");          d->console_handle = console_start_slave(devinit->machine, "fcom");
438    
439          /*  A PCI bus:  */          /*  A PCI bus:  */
440          d->pcibus = bus_pci_init(devinit->irq_nr);          d->pcibus = bus_pci_init(
441                devinit->irq_nr,    /*  PCI controller irq  */
442                0x7c000000,         /*  PCI device io offset  */
443                0x80000000,         /*  PCI device mem offset  */
444                0x00000000,         /*  PCI port base  */
445                0x00000000,         /*  PCI mem base  */
446                0,                  /*  PCI irq base: TODO  */
447                0x7c000000,         /*  ISA port base  */
448                0x80000000,         /*  ISA mem base  */
449                32);                /*  ISA port base  */
450    
451          /*  ... with some default devices for known machine types:  */          /*  ... with some default devices for known machine types:  */
452          switch (devinit->machine->machine_type) {          switch (devinit->machine->machine_type) {
453          case MACHINE_CATS:          case MACHINE_CATS:
454                  bus_pci_add(devinit->machine, d->pcibus,                  bus_pci_add(devinit->machine, d->pcibus,
455                      devinit->machine->memory, 0xc0, 7, 0,                      devinit->machine->memory, 0xc0, 7, 0, "ali_m1543");
456                      pci_ali_m1543_init, pci_ali_m1543_rr);                  bus_pci_add(devinit->machine, d->pcibus,
457                  /*  bus_pci_add(devinit->machine, d->pcibus,                      devinit->machine->memory, 0xc0, 10, 0, "dec21143");
                     devinit->machine->memory, 0xc0, 10, 0,  
                     pci_dec21143_init, pci_dec21143_rr);  */  
458                  bus_pci_add(devinit->machine, d->pcibus,                  bus_pci_add(devinit->machine, d->pcibus,
459                      devinit->machine->memory, 0xc0, 16, 0,                      devinit->machine->memory, 0xc0, 16, 0, "ali_m5229");
                     pci_ali_m5229_init, pci_ali_m5229_rr);  
460                  break;                  break;
461          case MACHINE_NETWINDER:          case MACHINE_NETWINDER:
462                  bus_pci_add(devinit->machine, d->pcibus,                  bus_pci_add(devinit->machine, d->pcibus,
463                      devinit->machine->memory, 0xc0, 11, 0,                      devinit->machine->memory, 0xc0, 11, 0, "symphony_83c553");
                     pci_symphony_83c553_init, pci_symphony_83c553_rr);  
464                  bus_pci_add(devinit->machine, d->pcibus,                  bus_pci_add(devinit->machine, d->pcibus,
465                      devinit->machine->memory, 0xc0, 11, 1,                      devinit->machine->memory, 0xc0, 11, 1, "symphony_82c105");
                     pci_symphony_82c105_init, pci_symphony_82c105_rr);  
466                  break;                  break;
467          default:fatal("footbridge: unimplemented machine type.\n");          default:fatal("footbridge: unimplemented machine type.\n");
468                  exit(1);                  exit(1);
# Line 468  int devinit_footbridge(struct devinit *d Line 471  int devinit_footbridge(struct devinit *d
471          /*  PCI configuration space:  */          /*  PCI configuration space:  */
472          memory_device_register(devinit->machine->memory,          memory_device_register(devinit->machine->memory,
473              "footbridge_pci", pci_addr, 0x1000000,              "footbridge_pci", pci_addr, 0x1000000,
474              dev_footbridge_pci_access, d, MEM_DEFAULT, NULL);              dev_footbridge_pci_access, d, DM_DEFAULT, NULL);
475    
476          /*  Timer ticks:  */          /*  Timer ticks:  */
477          for (i=0; i<N_FOOTBRIDGE_TIMERS; i++) {          for (i=0; i<N_FOOTBRIDGE_TIMERS; i++) {

Legend:
Removed from v.19  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26