/[gxemul]/trunk/src/devices/dev_kn02.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_kn02.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) 2003-2006  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-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_kn02.c,v 1.21 2006/01/01 13:17:16 debug Exp $   *  $Id: dev_kn02.c,v 1.26 2007/02/10 14:20:52 debug Exp $
29   *     *  
30   *  KN02 stuff ("3MAX", DECstation type 2).  See include/dec_kn02.h for more   *  KN02 mainbus (TurboChannel interrupt controller).
31   *  details.   *
32     *  Used in DECstation type 2 ("3MAX").  See include/dec_kn02.h for more info.
33   */   */
34    
35  #include <stdio.h>  #include <stdio.h>
# Line 36  Line 37 
37  #include <string.h>  #include <string.h>
38    
39  #include "cpu.h"  #include "cpu.h"
40  #include "devices.h"  #include "device.h"
41    #include "interrupt.h"
42    #include "machine.h"
43  #include "memory.h"  #include "memory.h"
44  #include "misc.h"  #include "misc.h"
45    
46    
47  #define DEV_KN02_LENGTH         0x1000  #define DEV_KN02_LENGTH         0x1000
48    
49    
50    struct kn02_data {
51            uint8_t         csr[sizeof(uint32_t)];
52    
53            /*  Dummy fill bytes, so dyntrans can be used:  */
54            uint8_t         filler[DEV_KN02_LENGTH - sizeof(uint32_t)];
55    
56            struct interrupt irq;
57            int             int_asserted;
58    };
59    
60    
61  /*  /*
62   *  dev_kn02_access():   *  kn02_interrupt_assert(), kn02_interrupt_deassert():
63     *
64     *  Called whenever a KN02 (TurboChannel) interrupt is asserted/deasserted.
65   */   */
66    void kn02_interrupt_assert(struct interrupt *interrupt)
67    {
68            struct kn02_data *d = interrupt->extra;
69            d->csr[0] |= interrupt->line;
70            if (d->csr[0] & d->csr[2] && !d->int_asserted) {
71                    d->int_asserted = 1;
72                    INTERRUPT_ASSERT(d->irq);
73            }
74    }
75    void kn02_interrupt_deassert(struct interrupt *interrupt)
76    {
77            struct kn02_data *d = interrupt->extra;
78            d->csr[0] &= ~interrupt->line;
79            if (!(d->csr[0] & d->csr[2]) && d->int_asserted) {
80                    d->int_asserted = 0;
81                    INTERRUPT_DEASSERT(d->irq);
82            }
83    }
84    
85    
86  DEVICE_ACCESS(kn02)  DEVICE_ACCESS(kn02)
87  {  {
88          struct kn02_csr *d = extra;          struct kn02_data *d = extra;
89          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
90    
91          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 69  DEVICE_ACCESS(kn02) Line 106  DEVICE_ACCESS(kn02)
106                           *  LEDs in the emulator, so those bits are just                           *  LEDs in the emulator, so those bits are just
107                           *  ignored.)                           *  ignored.)
108                           */                           */
109                            int old_assert = (d->csr[0] & d->csr[2])? 1 : 0;
110                            int new_assert;
111                          /* fatal("[ kn02: write to CSR: 0x%08x ]\n", idata); */                          /* fatal("[ kn02: write to CSR: 0x%08x ]\n", idata); */
112    
113                          d->csr[1] = (idata >> 8) & 255;                          d->csr[1] = (idata >> 8) & 255;
114                          d->csr[2] = (idata >> 16) & 255;                          d->csr[2] = (idata >> 16) & 255;
115    
116                          /*  Recalculate interrupt assertions:  */                          /*  Recalculate interrupt assertions:  */
117                          cpu_interrupt(cpu, 8);                          new_assert = (d->csr[0] & d->csr[2])? 1 : 0;
118                            if (new_assert != old_assert) {
119                                    if (new_assert) {
120                                            INTERRUPT_ASSERT(d->irq);
121                                            d->int_asserted = 1;
122                                    } else {
123                                            INTERRUPT_DEASSERT(d->irq);
124                                            d->int_asserted = 0;
125                                    }
126                            }
127                  }                  }
128                  break;                  break;
129          default:          default:
# Line 95  DEVICE_ACCESS(kn02) Line 143  DEVICE_ACCESS(kn02)
143  }  }
144    
145    
146  /*  DEVINIT(kn02)
  *  dev_kn02_init():  
  */  
 struct kn02_csr *dev_kn02_init(struct cpu *cpu, struct memory *mem,  
         uint64_t baseaddr)  
147  {  {
148          struct kn02_csr *d;          struct kn02_data *d;
149            int i;
150    
151          d = malloc(sizeof(struct kn02_csr));          d = malloc(sizeof(struct kn02_data));
152          if (d == NULL) {          if (d == NULL) {
153                  fprintf(stderr, "out of memory\n");                  fprintf(stderr, "out of memory\n");
154                  exit(1);                  exit(1);
155          }          }
156          memset(d, 0, sizeof(struct kn02_csr));          memset(d, 0, sizeof(struct kn02_data));
157    
158            /*  Connect the KN02 to a specific MIPS CPU interrupt line:  */
159            INTERRUPT_CONNECT(devinit->interrupt_path, d->irq);
160    
161          memory_device_register(mem, "kn02", baseaddr, DEV_KN02_LENGTH,          /*  Register the 8 possible TurboChannel interrupts:  */
162              dev_kn02_access, d, DM_DYNTRANS_OK, &d->csr[0]);          for (i=0; i<8; i++) {
163                    struct interrupt template;
164                    char tmpstr[300];
165                    snprintf(tmpstr, sizeof(tmpstr), "%s.kn02.%i",
166                        devinit->interrupt_path, i);
167                    memset(&template, 0, sizeof(template));
168                    template.line = 1 << i;
169                    template.name = tmpstr;
170                    template.extra = d;
171                    template.interrupt_assert = kn02_interrupt_assert;
172                    template.interrupt_deassert = kn02_interrupt_deassert;
173                    interrupt_handler_register(&template);
174            }
175    
176          return d;          memory_device_register(devinit->machine->memory, devinit->name,
177                devinit->addr, DEV_KN02_LENGTH, dev_kn02_access, d,
178                DM_DYNTRANS_OK, &d->csr[0]);
179    
180            return 1;
181  }  }
182    

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

  ViewVC Help
Powered by ViewVC 1.1.26