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

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

revision 21 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  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_i80321.c,v 1.5 2005/11/13 00:14:09 debug Exp $   *  $Id: dev_i80321.c,v 1.14 2006/02/18 17:55:25 debug Exp $
29   *   *
30   *  i80321.  TODO: This is just a dummy so far.   *  Intel i80321 (ARM) core functionality.
31     *
32     *  TODO: This is mostly just a dummy device.
33     *  TODO 2: This is hardcoded for little endian emulation.
34   */   */
35    
36  #include <stdio.h>  #include <stdio.h>
37  #include <stdlib.h>  #include <stdlib.h>
38  #include <string.h>  #include <string.h>
39    
40    #include "bus_pci.h"
41  #include "cpu.h"  #include "cpu.h"
42  #include "device.h"  #include "device.h"
43    #include "devices.h"
44  #include "machine.h"  #include "machine.h"
45  #include "memory.h"  #include "memory.h"
46  #include "misc.h"  #include "misc.h"
# Line 43  Line 48 
48    
49  #include "i80321reg.h"  #include "i80321reg.h"
50    
51  #define DEV_I80321_LENGTH               VERDE_PMMR_SIZE  #define TICK_SHIFT              20
52    #define DEV_I80321_LENGTH       VERDE_PMMR_SIZE
53    
 struct i80321_data {  
         uint32_t        mcu_reg[VERDE_MCU_SIZE / sizeof(uint32_t)];  
 };  
54    
55    void dev_i80321_tick(struct cpu *cpu, void *extra)
56    {
57            /*  struct i80321_data *d = extra;  */
58            int do_timer_interrupt = 0;
59    
60  /*          if (cpu->cd.arm.tmr0 & TMRx_ENABLE) {
61   *  dev_i80321_access():                  do_timer_interrupt = 1;
62   */          }
63  int dev_i80321_access(struct cpu *cpu, struct memory *mem,  
64          uint64_t relative_addr, unsigned char *data, size_t len,          if (do_timer_interrupt) {
65          int writeflag, void *extra)                  cpu_interrupt(cpu, 9);
66                    cpu->cd.arm.tisr |= TISR_TMR0;
67            } else {
68                    cpu_interrupt_ack(cpu, 9);
69                    cpu->cd.arm.tisr &= ~TISR_TMR0;
70            }
71    }
72    
73            
74    DEVICE_ACCESS(i80321)
75  {  {
76          struct i80321_data *d = extra;          struct i80321_data *d = extra;
77          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
78          char *n = NULL;          char *n = NULL;
79            int i, bus, dev, func, reg;
80    
81          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
82                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
83    
84            /*  PCI configuration space:  */
85            if (relative_addr >= 0x100 && relative_addr < 0x140) {
86                    /*  TODO  */
87                    goto ret;
88            }
89    
90            /*  MCU registers:  */
91          if (relative_addr >= VERDE_MCU_BASE &&          if (relative_addr >= VERDE_MCU_BASE &&
92              relative_addr <  VERDE_MCU_BASE + VERDE_MCU_SIZE) {              relative_addr <  VERDE_MCU_BASE + VERDE_MCU_SIZE) {
93                  int regnr = (relative_addr - VERDE_MCU_BASE) / sizeof(uint32_t);                  int regnr = (relative_addr - VERDE_MCU_BASE) / sizeof(uint32_t);
# Line 73  int dev_i80321_access(struct cpu *cpu, s Line 97  int dev_i80321_access(struct cpu *cpu, s
97                          odata = d->mcu_reg[regnr];                          odata = d->mcu_reg[regnr];
98          }          }
99    
100    
101          switch (relative_addr) {          switch (relative_addr) {
102    
103            /*  Address Translation Unit:  */
104            case VERDE_ATU_BASE + ATU_IALR0:
105            case VERDE_ATU_BASE + ATU_IATVR0:
106            case VERDE_ATU_BASE + ATU_IALR1:
107            case VERDE_ATU_BASE + ATU_IALR2:
108            case VERDE_ATU_BASE + ATU_IATVR2:
109            case VERDE_ATU_BASE + ATU_OIOWTVR:
110            case VERDE_ATU_BASE + ATU_OMWTVR0:
111            case VERDE_ATU_BASE + ATU_OUMWTVR0:
112            case VERDE_ATU_BASE + ATU_OMWTVR1:
113            case VERDE_ATU_BASE + ATU_OUMWTVR1:
114                    /*  Ignoring these for now. TODO  */
115                    break;
116            case VERDE_ATU_BASE + ATU_ATUCR:
117                    /*  ATU configuration register; ignored for now. TODO  */
118                    break;
119            case VERDE_ATU_BASE + ATU_PCSR:
120                    /*  TODO: Temporary hack to allow NetBSD/evbarm to
121                        reboot itself.  Should be rewritten as soon as possible!  */
122                    if (writeflag == MEM_WRITE && idata == 0x30) {
123                            int j;
124                            for (j=0; j<cpu->machine->ncpus; j++)
125                                    cpu->machine->cpus[j]->running = 0;
126                            cpu->machine->exit_without_entering_debugger = 1;
127                    }
128                    break;
129            case VERDE_ATU_BASE + ATU_ATUIMR:
130            case VERDE_ATU_BASE + ATU_IABAR3:
131            case VERDE_ATU_BASE + ATU_IAUBAR3:
132            case VERDE_ATU_BASE + ATU_IALR3:
133            case VERDE_ATU_BASE + ATU_IATVR3:
134                    /*  Ignoring these for now. TODO  */
135                    break;
136            case VERDE_ATU_BASE + ATU_OCCAR:
137                    /*  PCI address  */
138                    if (writeflag == MEM_WRITE) {
139                            d->pci_addr = idata;
140                            bus_pci_decompose_1(idata, &bus, &dev, &func, &reg);
141                            bus = 0;        /*  NOTE  */
142                            bus_pci_setaddr(cpu, d->pci_bus, bus, dev, func, reg);
143                    } else {
144                            odata = d->pci_addr;
145                    }
146                    break;
147            case VERDE_ATU_BASE + ATU_OCCDR:
148            case VERDE_ATU_BASE + ATU_OCCDR + 1:
149            case VERDE_ATU_BASE + ATU_OCCDR + 2:
150            case VERDE_ATU_BASE + ATU_OCCDR + 3:
151                    /*  PCI data  */
152                    if (writeflag == MEM_READ) {
153                            uint64_t tmp;
154                            bus_pci_data_access(cpu, d->pci_bus, &tmp,
155                                sizeof(uint32_t), MEM_READ);
156                            switch (relative_addr) {
157                            case VERDE_ATU_BASE + ATU_OCCDR + 1:
158                                    odata = tmp >> 8; break;
159                            case VERDE_ATU_BASE + ATU_OCCDR + 2:
160                                    odata = tmp >> 16; break;
161                            case VERDE_ATU_BASE + ATU_OCCDR + 3:
162                                    odata = tmp >> 24; break;
163                            default:odata = tmp;
164                            }
165                    } else {
166                            uint64_t tmp;
167                            int r = relative_addr - (VERDE_ATU_BASE + ATU_OCCDR);
168                            bus_pci_data_access(cpu, d->pci_bus, &tmp,
169                                sizeof(uint32_t), MEM_READ);
170                            for (i=0; i<len; i++) {
171                                    uint8_t b = idata >> (i*8);
172                                    tmp &= ~(0xff << ((r+i)*8));
173                                    tmp |= b << ((r+i)*8);
174                            }
175                            tmp &= 0xffffffff;  /* needed because << is 32-bit */
176                            bus_pci_data_access(cpu, d->pci_bus, &tmp,
177                                sizeof(uint32_t), MEM_WRITE);
178                    }
179                    break;
180            case VERDE_ATU_BASE + ATU_PCIXSR:
181                    odata = 0;              /*  TODO  */
182                    break;
183    
184            /*  Memory Controller Unit:  */
185          case VERDE_MCU_BASE + MCU_SDBR:          case VERDE_MCU_BASE + MCU_SDBR:
186                  n = "MCU_SDBR";                  n = "MCU_SDBR";
187                  break;                  break;
# Line 103  int dev_i80321_access(struct cpu *cpu, s Line 210  int dev_i80321_access(struct cpu *cpu, s
210                  }                  }
211          }          }
212    
213    ret:
214          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)
215                  memory_writemax64(cpu, data, len, odata);                  memory_writemax64(cpu, data, len, odata);
216    
# Line 110  int dev_i80321_access(struct cpu *cpu, s Line 218  int dev_i80321_access(struct cpu *cpu, s
218  }  }
219    
220    
221  /*  DEVINIT(i80321)
  *  devinit_i80321():  
  */  
 int devinit_i80321(struct devinit *devinit)  
222  {  {
223          struct i80321_data *d = malloc(sizeof(struct i80321_data));          struct i80321_data *d = malloc(sizeof(struct i80321_data));
224          uint32_t memsize = devinit->machine->physical_ram_in_mb * 1048576;          uint32_t memsize = devinit->machine->physical_ram_in_mb * 1048576;
# Line 126  int devinit_i80321(struct devinit *devin Line 231  int devinit_i80321(struct devinit *devin
231          memset(d, 0, sizeof(struct i80321_data));          memset(d, 0, sizeof(struct i80321_data));
232    
233          d->mcu_reg[MCU_SDBR / sizeof(uint32_t)] = base = 0xa0000000;          d->mcu_reg[MCU_SDBR / sizeof(uint32_t)] = base = 0xa0000000;
234          d->mcu_reg[MCU_SBR0 / sizeof(uint32_t)] = (base+memsize) >> 25;          d->mcu_reg[MCU_SBR0 / sizeof(uint32_t)] = (base + memsize) >> 25;
235          d->mcu_reg[MCU_SBR1 / sizeof(uint32_t)] = (base+memsize) >> 25;          d->mcu_reg[MCU_SBR1 / sizeof(uint32_t)] = (base + memsize) >> 25;
236    
237            d->pci_bus = bus_pci_init(devinit->machine,
238                0 /*  TODO: pciirq  */,
239                0x90000000 /*  TODO: pci_io_offset  */,
240                0x90010000 /*  TODO: pci_mem_offset  */,
241                0xffff0000 /*  TODO: pci_portbase  */,
242                0x00000000 /*  TODO: pci_membase  */,
243                29 /*  TODO: pci_irqbase  */,
244                0x90000000 /*  TODO: isa_portbase  */,
245                0x90010000 /*  TODO: isa_membase  */,
246                0 /*  TODO: isa_irqbase  */);
247    
248          memory_device_register(devinit->machine->memory, devinit->name,          memory_device_register(devinit->machine->memory, devinit->name,
249              devinit->addr, DEV_I80321_LENGTH,              devinit->addr, DEV_I80321_LENGTH,
250              dev_i80321_access, d, DM_DEFAULT, NULL);              dev_i80321_access, d, DM_DEFAULT, NULL);
251    
252            machine_add_tickfunction(devinit->machine, dev_i80321_tick,
253                d, TICK_SHIFT);
254    
255            devinit->return_ptr = d;
256    
257          return 1;          return 1;
258  }  }
259    

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

  ViewVC Help
Powered by ViewVC 1.1.26