/[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 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  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.20 2005/11/13 00:14:09 debug Exp $   *  $Id: dev_kn02.c,v 1.28 2007/06/15 19:11:15 debug Exp $
29   *     *  
30   *  KN02 stuff ("3MAX", DECstation type 2).  See include/dec_kn02.h for more   *  COMMENT: DEC 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    #include "dec_kn02.h"
48    
49  #define DEV_KN02_LENGTH         0x1000  #define DEV_KN02_LENGTH         0x1000
50    
51    
52    struct kn02_data {
53            uint8_t         csr[sizeof(uint32_t)];
54    
55            /*  Dummy fill bytes, so dyntrans can be used:  */
56            uint8_t         filler[DEV_KN02_LENGTH - sizeof(uint32_t)];
57    
58            struct interrupt irq;
59            int             int_asserted;
60    };
61    
62    
63  /*  /*
64   *  dev_kn02_access():   *  kn02_interrupt_assert(), kn02_interrupt_deassert():
65     *
66     *  Called whenever a KN02 (TurboChannel) interrupt is asserted/deasserted.
67   */   */
68  int dev_kn02_access(struct cpu *cpu, struct memory *mem,  void kn02_interrupt_assert(struct interrupt *interrupt)
69          uint64_t relative_addr, unsigned char *data, size_t len,  {
70          int writeflag, void *extra)          struct kn02_data *d = interrupt->extra;
71            d->csr[0] |= interrupt->line;
72            if (d->csr[0] & d->csr[2] && !d->int_asserted) {
73                    d->int_asserted = 1;
74                    INTERRUPT_ASSERT(d->irq);
75            }
76    }
77    void kn02_interrupt_deassert(struct interrupt *interrupt)
78  {  {
79          struct kn02_csr *d = extra;          struct kn02_data *d = interrupt->extra;
80            d->csr[0] &= ~interrupt->line;
81            if (!(d->csr[0] & d->csr[2]) && d->int_asserted) {
82                    d->int_asserted = 0;
83                    INTERRUPT_DEASSERT(d->irq);
84            }
85    }
86    
87    
88    DEVICE_ACCESS(kn02)
89    {
90            struct kn02_data *d = extra;
91          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
92    
93          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
# Line 61  int dev_kn02_access(struct cpu *cpu, str Line 98  int dev_kn02_access(struct cpu *cpu, str
98                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
99                          odata = d->csr[0] + (d->csr[1] << 8) +                          odata = d->csr[0] + (d->csr[1] << 8) +
100                              (d->csr[2] << 16) + (d->csr[3] << 24);                              (d->csr[2] << 16) + (d->csr[3] << 24);
101    
102                          /* debug("[ kn02: read from CSR: 0x%08x ]\n", odata); */                          /* debug("[ kn02: read from CSR: 0x%08x ]\n", odata); */
103                  } else {                  } else {
104                          /*                          /*
# Line 71  int dev_kn02_access(struct cpu *cpu, str Line 109  int dev_kn02_access(struct cpu *cpu, str
109                           *  LEDs in the emulator, so those bits are just                           *  LEDs in the emulator, so those bits are just
110                           *  ignored.)                           *  ignored.)
111                           */                           */
112                            int old_assert = (d->csr[0] & d->csr[2])? 1 : 0;
113                            int new_assert;
114                          /* fatal("[ kn02: write to CSR: 0x%08x ]\n", idata); */                          /* fatal("[ kn02: write to CSR: 0x%08x ]\n", idata); */
115    
116                          d->csr[1] = (idata >> 8) & 255;                          d->csr[1] = (idata >> 8) & 255;
117                          d->csr[2] = (idata >> 16) & 255;                          d->csr[2] = (idata >> 16) & 255;
118    
119                          /*  Recalculate interrupt assertions:  */                          /*  Recalculate interrupt assertions:  */
120                          cpu_interrupt(cpu, 8);                          new_assert = (d->csr[0] & d->csr[2])? 1 : 0;
121                            if (new_assert != old_assert) {
122                                    if (new_assert) {
123                                            INTERRUPT_ASSERT(d->irq);
124                                            d->int_asserted = 1;
125                                    } else {
126                                            INTERRUPT_DEASSERT(d->irq);
127                                            d->int_asserted = 0;
128                                    }
129                            }
130                  }                  }
131                  break;                  break;
132          default:          default:
# Line 97  int dev_kn02_access(struct cpu *cpu, str Line 146  int dev_kn02_access(struct cpu *cpu, str
146  }  }
147    
148    
149  /*  DEVINIT(kn02)
  *  dev_kn02_init():  
  */  
 struct kn02_csr *dev_kn02_init(struct cpu *cpu, struct memory *mem,  
         uint64_t baseaddr)  
150  {  {
151          struct kn02_csr *d;          struct kn02_data *d;
152            uint32_t csr;
153          d = malloc(sizeof(struct kn02_csr));          int i;
154          if (d == NULL) {  
155                  fprintf(stderr, "out of memory\n");          CHECK_ALLOCATION(d = malloc(sizeof(struct kn02_data)));
156                  exit(1);          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            /*  Register the 8 possible TurboChannel interrupts:  */
162            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          }          }
         memset(d, 0, sizeof(struct kn02_csr));  
175    
176          memory_device_register(mem, "kn02", baseaddr, DEV_KN02_LENGTH,          /*
177              dev_kn02_access, d, DM_DYNTRANS_OK, &d->csr[0]);           *  Set initial value of the CSR. Note: If the KN02_CSR_NRMMOD bit
178             *  is not set, the 5000/200 PROM image loops forever.
179             */
180            csr = KN02_CSR_NRMMOD;
181            d->csr[0] = csr;
182            d->csr[1] = csr >> 8;
183            d->csr[2] = csr >> 16;
184            d->csr[3] = csr >> 24;
185    
186            memory_device_register(devinit->machine->memory, devinit->name,
187                devinit->addr, DEV_KN02_LENGTH, dev_kn02_access, d,
188                DM_DYNTRANS_OK, &d->csr[0]);
189    
190          return d;          return 1;
191  }  }
192    

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

  ViewVC Help
Powered by ViewVC 1.1.26