/[gxemul]/upstream/0.3.1/devices/dev_mp.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

Annotation of /upstream/0.3.1/devices/dev_mp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 5232 byte(s)
0.3.1
1 dpavlin 2 /*
2     * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28     * $Id: dev_mp.c,v 1.25 2005/02/25 06:27:48 debug Exp $
29     *
30     * This is a fake multiprocessor (MP) device. It can be useful for
31     * theoretical experiments, but probably bares no resemblance to any
32     * multiprocessor controller used in any real machine.
33     */
34    
35     #include <stdio.h>
36     #include <stdlib.h>
37     #include <string.h>
38    
39     #include "cpu.h"
40     #include "cpu_mips.h"
41     #include "device.h"
42     #include "machine.h"
43     #include "memory.h"
44     #include "misc.h"
45     #include "mp.h"
46    
47    
48     struct mp_data {
49     struct cpu **cpus;
50     uint64_t startup_addr;
51     uint64_t stack_addr;
52     uint64_t pause_addr;
53     };
54    
55    
56     /*
57     * dev_mp_access():
58     */
59     int dev_mp_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr,
60     unsigned char *data, size_t len, int writeflag, void *extra)
61     {
62     struct mp_data *d = extra;
63     int i, which_cpu;
64     uint64_t idata = 0, odata = 0;
65    
66     idata = memory_readmax64(cpu, data, len);
67    
68     /*
69     * NOTE: It is up to the user of this device to read or write
70     * correct addresses. (A write to NCPUS is pretty useless,
71     * for example.)
72     */
73    
74     switch (relative_addr) {
75    
76     case DEV_MP_WHOAMI:
77     odata = cpu->cpu_id;
78     break;
79    
80     case DEV_MP_NCPUS:
81     odata = cpu->machine->ncpus;
82     break;
83    
84     case DEV_MP_STARTUPCPU:
85     which_cpu = idata;
86     d->cpus[which_cpu]->pc = d->startup_addr;
87     switch (cpu->machine->arch) {
88     case ARCH_MIPS:
89     d->cpus[which_cpu]->cd.mips.gpr[MIPS_GPR_SP] =
90     d->stack_addr;
91     break;
92     case ARCH_PPC:
93     d->cpus[which_cpu]->cd.ppc.gpr[1] = d->stack_addr;
94     break;
95     default:
96     fatal("dev_mp(): DEV_MP_STARTUPCPU: not for this"
97     " arch yet!\n");
98     exit(1);
99     }
100     d->cpus[which_cpu]->running = 1;
101     /* debug("[ dev_mp: starting up cpu%i at 0x%llx ]\n",
102     which_cpu, (long long)d->startup_addr); */
103     break;
104    
105     case DEV_MP_STARTUPADDR:
106     if (len==4 && (idata >> 32) == 0 && (idata & 0x80000000ULL))
107     idata |= 0xffffffff00000000ULL;
108     d->startup_addr = idata;
109     break;
110    
111     case DEV_MP_PAUSE_ADDR:
112     d->pause_addr = idata;
113     break;
114    
115     case DEV_MP_PAUSE_CPU:
116     /* Pause all cpus except our selves: */
117     which_cpu = idata;
118    
119     for (i=0; i<cpu->machine->ncpus; i++)
120     if (i!=which_cpu)
121     d->cpus[i]->running = 0;
122     break;
123    
124     case DEV_MP_UNPAUSE_CPU:
125     /* Unpause all cpus except our selves: */
126     which_cpu = idata;
127     for (i=0; i<cpu->machine->ncpus; i++)
128     if (i!=which_cpu)
129     d->cpus[i]->running = 1;
130     break;
131    
132     case DEV_MP_STARTUPSTACK:
133     if (len == 4 && (idata >> 32) == 0 && (idata & 0x80000000ULL))
134     idata |= 0xffffffff00000000ULL;
135     d->stack_addr = idata;
136     break;
137    
138     case DEV_MP_HARDWARE_RANDOM:
139     /* Return (up to) 64 bits of "hardware random": */
140     odata = random();
141     odata = (odata << 31) ^ random();
142     odata = (odata << 31) ^ random();
143     break;
144    
145     case DEV_MP_MEMORY:
146     /*
147     * Return the number of bytes of memory in the system.
148     *
149     * (It is assumed to be located at physical address 0.
150     * It is actually located at machine->memory_offset_in_mb
151     * but that is only used for SGI emulation so far.)
152     */
153     odata = cpu->machine->physical_ram_in_mb * 1048576;
154     break;
155    
156     default:
157     fatal("[ dev_mp: unimplemented relative addr 0x%x ]\n",
158     relative_addr);
159     }
160    
161     if (writeflag == MEM_READ)
162     memory_writemax64(cpu, data, len, odata);
163    
164     return 1;
165     }
166    
167    
168     /*
169     * devinit_mp():
170     */
171     int devinit_mp(struct devinit *devinit)
172     {
173     struct mp_data *d;
174     d = malloc(sizeof(struct mp_data));
175     if (d == NULL) {
176     fprintf(stderr, "out of memory\n");
177     exit(1);
178     }
179     memset(d, 0, sizeof(struct mp_data));
180     d->cpus = devinit->machine->cpus;
181     d->startup_addr = INITIAL_PC;
182     d->stack_addr = INITIAL_STACK_POINTER;
183    
184     memory_device_register(devinit->machine->memory,
185     devinit->name, devinit->addr, DEV_MP_LENGTH,
186     dev_mp_access, d, MEM_DEFAULT, NULL);
187    
188     return 1;
189     }
190    

  ViewVC Help
Powered by ViewVC 1.1.26