--- trunk/src/devices/dev_footbridge.c 2007/10/08 16:18:51 14 +++ trunk/src/devices/dev_footbridge.c 2007/10/08 16:19:11 18 @@ -25,15 +25,19 @@ * SUCH DAMAGE. * * - * $Id: dev_footbridge.c,v 1.22 2005/10/07 15:10:02 debug Exp $ + * $Id: dev_footbridge.c,v 1.26 2005/10/26 14:37:04 debug Exp $ * * Footbridge. Used in Netwinder and Cats. * * TODO: Most things. For example: * + * o) Fix the timer TODO (see below). + * * o) Add actual support for the fcom serial port. + * * o) FIQs. - * o) Lots of other things. + * + * o) .. */ #include @@ -54,6 +58,7 @@ #define DEV_FOOTBRIDGE_TICK_SHIFT 14 #define DEV_FOOTBRIDGE_LENGTH 0x400 +#define TIMER_POLL_THRESHOLD 15 /* @@ -68,6 +73,9 @@ int i; struct footbridge_data *d = (struct footbridge_data *) extra; + if (!d->timer_being_read) + d->timer_poll_mode = 0; + for (i=0; itimer_control[i] & TIMER_FCLK_16) @@ -110,10 +118,10 @@ uint64_t idata = 0, odata = 0; int x; - idata = memory_readmax64(cpu, data, len); - - if (writeflag == MEM_WRITE) + if (writeflag == MEM_WRITE) { + idata = memory_readmax64(cpu, data, len); fatal("[ footbridge_isa: WARNING/TODO: write! ]\n"); + } /* * NetBSD seems to want a value of 0x20 + x, where x is the highest @@ -162,7 +170,8 @@ int bus, device, function, regnr, res; uint64_t pci_word; - idata = memory_readmax64(cpu, data, len); + if (writeflag == MEM_WRITE) + idata = memory_readmax64(cpu, data, len); bus = (relative_addr >> 16) & 0xff; device = (relative_addr >> 11) & 0x1f; @@ -218,7 +227,8 @@ uint64_t idata = 0, odata = 0; int timer_nr = 0; - idata = memory_readmax64(cpu, data, len); + if (writeflag == MEM_WRITE) + idata = memory_readmax64(cpu, data, len); if (relative_addr >= TIMER_1_LOAD && relative_addr <= TIMER_4_CLEAR) { timer_nr = (relative_addr >> 5) & (N_FOOTBRIDGE_TIMERS - 1); @@ -276,10 +286,10 @@ d->irq_enable |= idata; cpu_interrupt(cpu, 64); } else { + odata = d->irq_enable; fatal("[ WARNING: footbridge read from " "ENABLE SET? ]\n"); exit(1); - odata = d->irq_enable; } break; @@ -288,10 +298,10 @@ d->irq_enable &= ~idata; cpu_interrupt(cpu, 64); } else { + odata = d->irq_enable; fatal("[ WARNING: footbridge read from " "ENABLE CLEAR? ]\n"); exit(1); - odata = d->irq_enable; } break; @@ -338,8 +348,19 @@ case TIMER_1_VALUE: if (writeflag == MEM_READ) { - dev_footbridge_tick(cpu, d); + /* + * TODO: This is INCORRECT! but speeds up NetBSD + * and OpenBSD boot sequences. A better solution + * would be to only call dev_footbridge_tick() if + * the timer is polled "very often" (such as during + * bootup), but not during normal operation. + */ + d->timer_being_read = 1; + d->timer_poll_mode ++; + if (d->timer_poll_mode > TIMER_POLL_THRESHOLD) + dev_footbridge_tick(cpu, d); odata = d->timer_value[timer_nr]; + d->timer_being_read = 0; } else d->timer_value[timer_nr] = idata & TIMER_MAX_VAL; break; @@ -425,6 +446,9 @@ bus_pci_add(devinit->machine, d->pcibus, devinit->machine->memory, 0xc0, 7, 0, pci_ali_m1543_init, pci_ali_m1543_rr); + /* bus_pci_add(devinit->machine, d->pcibus, + devinit->machine->memory, 0xc0, 10, 0, + pci_dec21143_init, pci_dec21143_rr); */ bus_pci_add(devinit->machine, d->pcibus, devinit->machine->memory, 0xc0, 16, 0, pci_ali_m5229_init, pci_ali_m5229_rr);