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

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

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 34 by dpavlin, Mon Oct 8 16:21:17 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  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_v3.c,v 1.4 2006/02/18 17:55:25 debug Exp $   *  $Id: dev_v3.c,v 1.8 2007/01/20 13:26:20 debug Exp $
29   *     *  
30   *  V3 Semiconductor PCI controller.   *  V3 Semiconductor PCI controller.
31   *   *
32     *  The ISA interrupt controller part forwards ISA interrupts as follows
33     *  (on Algor P5064):
34     *
35     *      ISA interrupt 3 and 4           -> MIPS interrupt 4 ("Local")
36     *      All other ISA interrupts        -> MIPS interrupt 2 ("ISA")
37     *
38   *  See NetBSD's src/sys/arch/algor/pci/ for details.   *  See NetBSD's src/sys/arch/algor/pci/ for details.
39   */   */
40    
# Line 40  Line 46 
46  #include "cpu.h"  #include "cpu.h"
47  #include "device.h"  #include "device.h"
48  #include "devices.h"  #include "devices.h"
49    #include "interrupt.h"
50  #include "machine.h"  #include "machine.h"
51  #include "memory.h"  #include "memory.h"
52  #include "misc.h"  #include "misc.h"
53    
54    
55    struct v3_data {
56            struct interrupt        irq_isa;
57            struct interrupt        irq_local;
58            uint8_t                 secondary_mask1;
59    
60            struct pic8259_data* pic1;
61            struct pic8259_data* pic2;
62            int                     *ptr_to_pending_timer_interrupts;
63    
64            struct pci_data         *pci_data;
65            uint16_t                lb_map0;
66    };
67    
68    
69    /*
70     *  v3_isa_interrupt_common():
71     */
72    void v3_isa_interrupt_common(struct v3_data *d, int old_isa_assert)
73    {
74            int new_isa_assert;
75    
76            /*  Any interrupt assertions on PIC2 go to irq 2 on PIC1  */
77            /*  (TODO: don't hardcode this here)  */
78            if (d->pic2->irr & ~d->pic2->ier)
79                    d->pic1->irr |= 0x04;
80            else
81                    d->pic1->irr &= ~0x04;
82    
83            new_isa_assert = d->pic1->irr & ~d->pic1->ier;
84    
85            if (old_isa_assert == new_isa_assert)
86                    return;
87    
88            if (new_isa_assert & d->secondary_mask1)
89                    INTERRUPT_ASSERT(d->irq_local);
90            else
91                    INTERRUPT_DEASSERT(d->irq_local);
92    
93            if (new_isa_assert & ~d->secondary_mask1)
94                    INTERRUPT_ASSERT(d->irq_isa);
95            else
96                    INTERRUPT_DEASSERT(d->irq_isa);
97    }
98    
99    
100    /*
101     *  v3_isa_interrupt_assert():
102     *
103     *  Called whenever an ISA device asserts an interrupt (0..15).
104     *  If the interrupt number is 16, then it is a re-assert.
105     */
106    void v3_isa_interrupt_assert(struct interrupt *interrupt)
107    {
108            struct v3_data *d = interrupt->extra;
109            int old_isa_assert, line = interrupt->line;
110            int mask = 1 << (line & 7);
111    
112            old_isa_assert = d->pic1->irr & ~d->pic1->ier;
113    
114            if (line < 8)
115                    d->pic1->irr |= mask;
116            else if (line < 16)
117                    d->pic2->irr |= mask;
118    
119            v3_isa_interrupt_common(d, old_isa_assert);
120    }
121    
122    
123    /*
124     *  v3_isa_interrupt_deassert():
125     *
126     *  Called whenever an ISA device deasserts an interrupt (0..15).
127     *  If the interrupt number is 16, then it is a re-assert.
128     */
129    void v3_isa_interrupt_deassert(struct interrupt *interrupt)
130    {
131            struct v3_data *d = interrupt->extra;
132            int line = interrupt->line, mask = 1 << (line & 7);
133            int old_irr1 = d->pic1->irr, old_isa_assert;
134    
135            old_isa_assert = old_irr1 & ~d->pic1->ier;
136    
137            if (line < 8)
138                    d->pic1->irr &= ~mask;
139            else if (line < 16)
140                    d->pic2->irr &= ~mask;
141    
142            /*  If IRQ 0 has been cleared, then this is a timer interrupt.
143                Let's ack it here:  */
144            if (old_irr1 & 1 && !(d->pic1->irr & 1) &&
145                d->ptr_to_pending_timer_interrupts != NULL &&
146                (*d->ptr_to_pending_timer_interrupts) > 0)
147                    (*d->ptr_to_pending_timer_interrupts) --;
148    
149            v3_isa_interrupt_common(d, old_isa_assert);
150    }
151    
152    
153  DEVICE_ACCESS(v3_pci)  DEVICE_ACCESS(v3_pci)
154  {  {
155          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
# Line 138  DEVICE_ACCESS(v3) Line 243  DEVICE_ACCESS(v3)
243  }  }
244    
245    
246  struct v3_data *dev_v3_init(struct machine *machine, struct memory *mem)  DEVINIT(v3)
247  {  {
248          struct v3_data *d;          struct v3_data *d;
249            uint32_t isa_port_base = 0x1d000000;
250            char tmpstr[200];
251            char isa_irq_base[200];
252            char pci_irq_base[200];
253            int i;
254    
255          d = malloc(sizeof(struct v3_data));          d = malloc(sizeof(struct v3_data));
256          if (d == NULL) {          if (d == NULL) {
# Line 149  struct v3_data *dev_v3_init(struct machi Line 259  struct v3_data *dev_v3_init(struct machi
259          }          }
260          memset(d, 0, sizeof(struct v3_data));          memset(d, 0, sizeof(struct v3_data));
261    
262            switch (devinit->machine->machine_type) {
263            case MACHINE_ALGOR:
264                    snprintf(tmpstr, sizeof(tmpstr), "%s.4",
265                        devinit->interrupt_path);
266                    INTERRUPT_CONNECT(tmpstr, d->irq_local);
267    
268                    snprintf(tmpstr, sizeof(tmpstr), "%s.2",
269                        devinit->interrupt_path);
270                    INTERRUPT_CONNECT(tmpstr, d->irq_isa);
271    
272                    d->secondary_mask1 = 0x18;
273                    break;
274    
275            default:fatal("!\n! WARNING: v3 for non-implemented machine"
276                        " type %i\n!\n", devinit->machine->machine_type);
277                    exit(1);
278            }
279    
280            /*
281             *  Register the 16 possible ISA interrupts, plus a dummy. The
282             *  dummy is used by re-asserts.
283             */
284            for (i=0; i<17; i++) {
285                    struct interrupt template;
286                    char n[300];
287                    snprintf(n, sizeof(n), "%s.v3.isa.%i",
288                        devinit->interrupt_path, i);
289                    memset(&template, 0, sizeof(template));
290                    template.line = i;
291                    template.name = n;
292                    template.extra = d;
293                    template.interrupt_assert = v3_isa_interrupt_assert;
294                    template.interrupt_deassert = v3_isa_interrupt_deassert;
295                    interrupt_handler_register(&template);
296            }
297    
298            /*  Register two 8259 PICs:  */
299            snprintf(tmpstr, sizeof(tmpstr), "8259 irq=%s.v3.isa.16 addr=0x%llx",
300                devinit->interrupt_path, (long long)(isa_port_base + 0x20));
301            d->pic1 = devinit->machine->isa_pic_data.pic1 =
302                device_add(devinit->machine, tmpstr);
303            d->ptr_to_pending_timer_interrupts =
304                devinit->machine->isa_pic_data.pending_timer_interrupts;
305    
306            snprintf(tmpstr, sizeof(tmpstr), "8259 irq=%s.v3.isa.2 addr=0x%llx",
307                devinit->interrupt_path, (long long)(isa_port_base + 0xa0));
308            d->pic2 = devinit->machine->isa_pic_data.pic2 =
309                device_add(devinit->machine, tmpstr);
310    
311            snprintf(isa_irq_base, sizeof(isa_irq_base), "%s.v3",
312                devinit->interrupt_path);
313            snprintf(pci_irq_base, sizeof(pci_irq_base), "%s.v3",
314                devinit->interrupt_path);
315    
316          /*  Register a PCI bus:  */          /*  Register a PCI bus:  */
317          d->pci_data = bus_pci_init(          d->pci_data = bus_pci_init(
318              machine,              devinit->machine,
319              0                   /*  pciirq: TODO  */,              pci_irq_base                /*  pciirq: TODO  */,
320              0x1d000000,         /*  pci device io offset  */              0x1d000000,                 /*  pci device io offset  */
321              0x11000000,         /*  pci device mem offset: TODO  */              0x11000000,                 /*  pci device mem offset: TODO  */
322              0x00000000,         /*  PCI portbase: TODO  */              0x00000000,                 /*  PCI portbase: TODO  */
323              0x00000000,         /*  PCI membase: TODO  */              0x00000000,                 /*  PCI membase: TODO  */
324              0x00000000,         /*  PCI irqbase: TODO  */              pci_irq_base,               /*  PCI irqbase  */
325              0x1d000000,         /*  ISA portbase  */              isa_port_base,              /*  ISA portbase  */
326              0x10000000,         /*  ISA membase  */              0x10000000,                 /*  ISA membase  */
327              8);                 /*  ISA irqbase  */              isa_irq_base);              /*  ISA irqbase  */
328    
329          switch (machine->machine_type) {          switch (devinit->machine->machine_type) {
330          case MACHINE_ALGOR:          case MACHINE_ALGOR:
331                  bus_pci_add(machine, d->pci_data, mem, 0, 2, 0, "piix3_isa");                  bus_pci_add(devinit->machine, d->pci_data,
332                  bus_pci_add(machine, d->pci_data, mem, 0, 2, 1, "piix3_ide");                      devinit->machine->memory, 0, 2, 0, "piix3_isa");
333                    bus_pci_add(devinit->machine, d->pci_data,
334                        devinit->machine->memory, 0, 2, 1, "piix3_ide");
335                  break;                  break;
336          default:fatal("!\n! WARNING: v3 for non-implemented machine"          default:fatal("!\n! WARNING: v3 for non-implemented machine"
337                      " type %i\n!\n", machine->machine_type);                      " type %i\n!\n", devinit->machine->machine_type);
338                  exit(1);                  exit(1);
339          }          }
340    
341          /*  PCI configuration space:  */          /*  PCI configuration space:  */
342          memory_device_register(mem, "v3_pci", 0x1ee00000, 0x100000,          memory_device_register(devinit->machine->memory, "v3_pci",
343              dev_v3_pci_access, d, DM_DEFAULT, NULL);              0x1ee00000, 0x100000, dev_v3_pci_access, d, DM_DEFAULT, NULL);
344    
345          /*  PCI controller:  */          /*  PCI controller:  */
346          memory_device_register(mem, "v3", 0x1ef00000, 0x1000,          memory_device_register(devinit->machine->memory, "v3",
347              dev_v3_access, d, DM_DEFAULT, NULL);              0x1ef00000, 0x1000, dev_v3_access, d, DM_DEFAULT, NULL);
348    
349          return d;          devinit->return_ptr = d->pci_data;
350    
351            return 1;
352  }  }
353    

Legend:
Removed from v.22  
changed lines
  Added in v.34

  ViewVC Help
Powered by ViewVC 1.1.26