Revision 420557e8

b/hw/iommu.c
1
/*
2
 * QEMU SPARC iommu emulation
3
 *
4
 * Copyright (c) 2003 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

  
26
/* debug iommu */
27
//#define DEBUG_IOMMU
28

  
29
/* The IOMMU registers occupy three pages in IO space. */
30
struct iommu_regs {
31
	/* First page */
32
	volatile unsigned long control;    /* IOMMU control */
33
	volatile unsigned long base;       /* Physical base of iopte page table */
34
	volatile unsigned long _unused1[3];
35
	volatile unsigned long tlbflush;   /* write only */
36
	volatile unsigned long pageflush;  /* write only */
37
	volatile unsigned long _unused2[1017];
38
	/* Second page */
39
	volatile unsigned long afsr;       /* Async-fault status register */
40
	volatile unsigned long afar;       /* Async-fault physical address */
41
	volatile unsigned long _unused3[2];
42
	volatile unsigned long sbuscfg0;   /* SBUS configuration registers, per-slot */
43
	volatile unsigned long sbuscfg1;
44
	volatile unsigned long sbuscfg2;
45
	volatile unsigned long sbuscfg3;
46
	volatile unsigned long mfsr;       /* Memory-fault status register */
47
	volatile unsigned long mfar;       /* Memory-fault physical address */
48
	volatile unsigned long _unused4[1014];
49
	/* Third page */
50
	volatile unsigned long mid;        /* IOMMU module-id */
51
};
52

  
53
#define IOMMU_CTRL_IMPL     0xf0000000 /* Implementation */
54
#define IOMMU_CTRL_VERS     0x0f000000 /* Version */
55
#define IOMMU_CTRL_RNGE     0x0000001c /* Mapping RANGE */
56
#define IOMMU_RNGE_16MB     0x00000000 /* 0xff000000 -> 0xffffffff */
57
#define IOMMU_RNGE_32MB     0x00000004 /* 0xfe000000 -> 0xffffffff */
58
#define IOMMU_RNGE_64MB     0x00000008 /* 0xfc000000 -> 0xffffffff */
59
#define IOMMU_RNGE_128MB    0x0000000c /* 0xf8000000 -> 0xffffffff */
60
#define IOMMU_RNGE_256MB    0x00000010 /* 0xf0000000 -> 0xffffffff */
61
#define IOMMU_RNGE_512MB    0x00000014 /* 0xe0000000 -> 0xffffffff */
62
#define IOMMU_RNGE_1GB      0x00000018 /* 0xc0000000 -> 0xffffffff */
63
#define IOMMU_RNGE_2GB      0x0000001c /* 0x80000000 -> 0xffffffff */
64
#define IOMMU_CTRL_ENAB     0x00000001 /* IOMMU Enable */
65

  
66
#define IOMMU_AFSR_ERR      0x80000000 /* LE, TO, or BE asserted */
67
#define IOMMU_AFSR_LE       0x40000000 /* SBUS reports error after transaction */
68
#define IOMMU_AFSR_TO       0x20000000 /* Write access took more than 12.8 us. */
69
#define IOMMU_AFSR_BE       0x10000000 /* Write access received error acknowledge */
70
#define IOMMU_AFSR_SIZE     0x0e000000 /* Size of transaction causing error */
71
#define IOMMU_AFSR_S        0x01000000 /* Sparc was in supervisor mode */
72
#define IOMMU_AFSR_RESV     0x00f00000 /* Reserver, forced to 0x8 by hardware */
73
#define IOMMU_AFSR_ME       0x00080000 /* Multiple errors occurred */
74
#define IOMMU_AFSR_RD       0x00040000 /* A read operation was in progress */
75
#define IOMMU_AFSR_FAV      0x00020000 /* IOMMU afar has valid contents */
76

  
77
#define IOMMU_SBCFG_SAB30   0x00010000 /* Phys-address bit 30 when bypass enabled */
78
#define IOMMU_SBCFG_BA16    0x00000004 /* Slave supports 16 byte bursts */
79
#define IOMMU_SBCFG_BA8     0x00000002 /* Slave supports 8 byte bursts */
80
#define IOMMU_SBCFG_BYPASS  0x00000001 /* Bypass IOMMU, treat all addresses
81
					  produced by this device as pure
82
					  physical. */
83

  
84
#define IOMMU_MFSR_ERR      0x80000000 /* One or more of PERR1 or PERR0 */
85
#define IOMMU_MFSR_S        0x01000000 /* Sparc was in supervisor mode */
86
#define IOMMU_MFSR_CPU      0x00800000 /* CPU transaction caused parity error */
87
#define IOMMU_MFSR_ME       0x00080000 /* Multiple parity errors occurred */
88
#define IOMMU_MFSR_PERR     0x00006000 /* high bit indicates parity error occurred
89
					  on the even word of the access, low bit
90
					  indicated odd word caused the parity error */
91
#define IOMMU_MFSR_BM       0x00001000 /* Error occurred while in boot mode */
92
#define IOMMU_MFSR_C        0x00000800 /* Address causing error was marked cacheable */
93
#define IOMMU_MFSR_RTYP     0x000000f0 /* Memory request transaction type */
94

  
95
#define IOMMU_MID_SBAE      0x001f0000 /* SBus arbitration enable */
96
#define IOMMU_MID_SE        0x00100000 /* Enables SCSI/ETHERNET arbitration */
97
#define IOMMU_MID_SB3       0x00080000 /* Enable SBUS device 3 arbitration */
98
#define IOMMU_MID_SB2       0x00040000 /* Enable SBUS device 2 arbitration */
99
#define IOMMU_MID_SB1       0x00020000 /* Enable SBUS device 1 arbitration */
100
#define IOMMU_MID_SB0       0x00010000 /* Enable SBUS device 0 arbitration */
101
#define IOMMU_MID_MID       0x0000000f /* Module-id, hardcoded to 0x8 */
102

  
103
/* The format of an iopte in the page tables */
104
#define IOPTE_PAGE          0x07ffff00 /* Physical page number (PA[30:12]) */
105
#define IOPTE_CACHE         0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
106
#define IOPTE_WRITE         0x00000004 /* Writeable */
107
#define IOPTE_VALID         0x00000002 /* IOPTE is valid */
108
#define IOPTE_WAZ           0x00000001 /* Write as zeros */
109

  
110
#define PHYS_JJ_IOMMU	0x10000000	/* First page of sun4m IOMMU */
111
#define PAGE_SHIFT      12
112
#define PAGE_SIZE       (1 << PAGE_SHIFT)
113
#define PAGE_MASK	(PAGE_SIZE - 1)
114

  
115
typedef struct IOMMUState {
116
    uint32_t regs[sizeof(struct iommu_regs)];
117
} IOMMUState;
118

  
119
static IOMMUState *ps;
120

  
121
static int iommu_io_memory;
122

  
123
static void iommu_reset(IOMMUState *s)
124
{
125
}
126

  
127
static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
128
{
129
    IOMMUState *s = opaque;
130
    uint32_t saddr;
131

  
132
    saddr = (addr - PHYS_JJ_IOMMU) >> 2;
133
    switch (saddr) {
134
    default:
135
	return s->regs[saddr];
136
	break;
137
    }
138
    return 0;
139
}
140

  
141
static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
142
{
143
    IOMMUState *s = opaque;
144
    uint32_t saddr;
145

  
146
    saddr = (addr - PHYS_JJ_IOMMU) >> 2;
147
    switch (saddr) {
148
    default:
149
	s->regs[saddr] = val;
150
	break;
151
    }
152
}
153

  
154
static CPUReadMemoryFunc *iommu_mem_read[3] = {
155
    iommu_mem_readw,
156
    iommu_mem_readw,
157
    iommu_mem_readw,
158
};
159

  
160
static CPUWriteMemoryFunc *iommu_mem_write[3] = {
161
    iommu_mem_writew,
162
    iommu_mem_writew,
163
    iommu_mem_writew,
164
};
165

  
166
uint32_t iommu_translate(uint32_t addr)
167
{
168
    uint32_t *iopte = (void *)(ps->regs[1] << 4), pa, iostart;
169

  
170
    switch (ps->regs[0] & IOMMU_CTRL_RNGE) {
171
    case IOMMU_RNGE_16MB:
172
	iostart = 0xff000000;
173
	break;
174
    case IOMMU_RNGE_32MB:
175
	iostart = 0xfe000000;
176
	break;
177
    case IOMMU_RNGE_64MB:
178
	iostart = 0xfc000000;
179
	break;
180
    case IOMMU_RNGE_128MB:
181
	iostart = 0xf8000000;
182
	break;
183
    case IOMMU_RNGE_256MB:
184
	iostart = 0xf0000000;
185
	break;
186
    case IOMMU_RNGE_512MB:
187
	iostart = 0xe0000000;
188
	break;
189
    case IOMMU_RNGE_1GB:
190
	iostart = 0xc0000000;
191
	break;
192
    default:
193
    case IOMMU_RNGE_2GB:
194
	iostart = 0x80000000;
195
	break;
196
    }
197

  
198
    iopte += ((addr - iostart) >> PAGE_SHIFT);
199
    cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0);
200
    bswap32s(&pa);
201
    pa = (pa & IOPTE_PAGE) << 4;		/* Loose higher bits of 36 */
202
    //return pa + PAGE_SIZE;
203
    return pa + (addr & PAGE_MASK);
204
}
205

  
206
void iommu_init()
207
{
208
    IOMMUState *s;
209

  
210
    s = qemu_mallocz(sizeof(IOMMUState));
211
    if (!s)
212
        return;
213

  
214
    iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s);
215
    cpu_register_physical_memory(PHYS_JJ_IOMMU, sizeof(struct iommu_regs),
216
                                 iommu_io_memory);
217
    
218
    iommu_reset(s);
219
    ps = s;
220
}
221

  
b/hw/lance.c
1
/*
2
 * QEMU Lance emulation
3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

  
26
/* debug LANCE card */
27
#define DEBUG_LANCE
28

  
29
#define PHYS_JJ_IOMMU	0x10000000	/* First page of sun4m IOMMU */
30
#define PHYS_JJ_LEDMA   0x78400010      /* ledma, off by 10 from unused SCSI */
31
#define PHYS_JJ_LE      0x78C00000      /* LANCE, typical sun4m */
32

  
33
#ifndef LANCE_LOG_TX_BUFFERS
34
#define LANCE_LOG_TX_BUFFERS 4
35
#define LANCE_LOG_RX_BUFFERS 4
36
#endif
37

  
38
#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
39
#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
40

  
41

  
42
#define LE_CSR0 0
43
#define LE_CSR1 1
44
#define LE_CSR2 2
45
#define LE_CSR3 3
46
#define LE_MAXREG (LE_CSR3 + 1)
47

  
48
#define LE_RDP  0
49
#define LE_RAP  1
50

  
51
#define LE_MO_PROM      0x8000  /* Enable promiscuous mode */
52

  
53
#define	LE_C0_ERR	0x8000	/* Error: set if BAB, SQE, MISS or ME is set */
54
#define	LE_C0_BABL	0x4000	/* BAB:  Babble: tx timeout. */
55
#define	LE_C0_CERR	0x2000	/* SQE:  Signal quality error */
56
#define	LE_C0_MISS	0x1000	/* MISS: Missed a packet */
57
#define	LE_C0_MERR	0x0800	/* ME:   Memory error */
58
#define	LE_C0_RINT	0x0400	/* Received interrupt */
59
#define	LE_C0_TINT	0x0200	/* Transmitter Interrupt */
60
#define	LE_C0_IDON	0x0100	/* IFIN: Init finished. */
61
#define	LE_C0_INTR	0x0080	/* Interrupt or error */
62
#define	LE_C0_INEA	0x0040	/* Interrupt enable */
63
#define	LE_C0_RXON	0x0020	/* Receiver on */
64
#define	LE_C0_TXON	0x0010	/* Transmitter on */
65
#define	LE_C0_TDMD	0x0008	/* Transmitter demand */
66
#define	LE_C0_STOP	0x0004	/* Stop the card */
67
#define	LE_C0_STRT	0x0002	/* Start the card */
68
#define	LE_C0_INIT	0x0001	/* Init the card */
69

  
70
#define	LE_C3_BSWP	0x4     /* SWAP */
71
#define	LE_C3_ACON	0x2	/* ALE Control */
72
#define	LE_C3_BCON	0x1	/* Byte control */
73

  
74
/* Receive message descriptor 1 */
75
#define LE_R1_OWN       0x80    /* Who owns the entry */
76
#define LE_R1_ERR       0x40    /* Error: if FRA, OFL, CRC or BUF is set */
77
#define LE_R1_FRA       0x20    /* FRA: Frame error */
78
#define LE_R1_OFL       0x10    /* OFL: Frame overflow */
79
#define LE_R1_CRC       0x08    /* CRC error */
80
#define LE_R1_BUF       0x04    /* BUF: Buffer error */
81
#define LE_R1_SOP       0x02    /* Start of packet */
82
#define LE_R1_EOP       0x01    /* End of packet */
83
#define LE_R1_POK       0x03    /* Packet is complete: SOP + EOP */
84

  
85
#define LE_T1_OWN       0x80    /* Lance owns the packet */
86
#define LE_T1_ERR       0x40    /* Error summary */
87
#define LE_T1_EMORE     0x10    /* Error: more than one retry needed */
88
#define LE_T1_EONE      0x08    /* Error: one retry needed */
89
#define LE_T1_EDEF      0x04    /* Error: deferred */
90
#define LE_T1_SOP       0x02    /* Start of packet */
91
#define LE_T1_EOP       0x01    /* End of packet */
92
#define LE_T1_POK	0x03	/* Packet is complete: SOP + EOP */
93

  
94
#define LE_T3_BUF       0x8000  /* Buffer error */
95
#define LE_T3_UFL       0x4000  /* Error underflow */
96
#define LE_T3_LCOL      0x1000  /* Error late collision */
97
#define LE_T3_CLOS      0x0800  /* Error carrier loss */
98
#define LE_T3_RTY       0x0400  /* Error retry */
99
#define LE_T3_TDR       0x03ff  /* Time Domain Reflectometry counter */
100

  
101
#define TX_RING_SIZE			(1 << (LANCE_LOG_TX_BUFFERS))
102
#define TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
103
#define TX_RING_LEN_BITS		((LANCE_LOG_TX_BUFFERS) << 29)
104

  
105
#define RX_RING_SIZE			(1 << (LANCE_LOG_RX_BUFFERS))
106
#define RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
107
#define RX_RING_LEN_BITS		((LANCE_LOG_RX_BUFFERS) << 29)
108

  
109
#define PKT_BUF_SZ		1544
110
#define RX_BUFF_SIZE            PKT_BUF_SZ
111
#define TX_BUFF_SIZE            PKT_BUF_SZ
112

  
113
struct lance_rx_desc {
114
	unsigned short rmd0;        /* low address of packet */
115
	unsigned char  rmd1_bits;   /* descriptor bits */
116
	unsigned char  rmd1_hadr;   /* high address of packet */
117
	short    length;    	    /* This length is 2s complement (negative)!
118
				     * Buffer length
119
				     */
120
	unsigned short mblength;    /* This is the actual number of bytes received */
121
};
122

  
123
struct lance_tx_desc {
124
	unsigned short tmd0;        /* low address of packet */
125
	unsigned char  tmd1_bits;   /* descriptor bits */
126
	unsigned char  tmd1_hadr;   /* high address of packet */
127
	short length;          	    /* Length is 2s complement (negative)! */
128
	unsigned short misc;
129
};
130

  
131
/* The LANCE initialization block, described in databook. */
132
/* On the Sparc, this block should be on a DMA region     */
133
struct lance_init_block {
134
	unsigned short mode;		/* Pre-set mode (reg. 15) */
135
	unsigned char phys_addr[6];     /* Physical ethernet address */
136
	unsigned filter[2];		/* Multicast filter. */
137

  
138
	/* Receive and transmit ring base, along with extra bits. */
139
	unsigned short rx_ptr;		/* receive descriptor addr */
140
	unsigned short rx_len;		/* receive len and high addr */
141
	unsigned short tx_ptr;		/* transmit descriptor addr */
142
	unsigned short tx_len;		/* transmit len and high addr */
143
    
144
	/* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
145
	struct lance_rx_desc brx_ring[RX_RING_SIZE];
146
	struct lance_tx_desc btx_ring[TX_RING_SIZE];
147
    
148
	char   tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
149
	char   pad[2];			/* align rx_buf for copy_and_sum(). */
150
	char   rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
151
};
152

  
153
#define LEDMA_REGS 4
154
#if 0
155
/* Structure to describe the current status of DMA registers on the Sparc */
156
struct sparc_dma_registers {
157
    uint32_t cond_reg;	/* DMA condition register */
158
    uint32_t st_addr;	/* Start address of this transfer */
159
    uint32_t cnt;	/* How many bytes to transfer */
160
    uint32_t dma_test;	/* DMA test register */
161
};
162
#endif
163

  
164
typedef struct LEDMAState {
165
    uint32_t regs[LEDMA_REGS];
166
} LEDMAState;
167

  
168
typedef struct LANCEState {
169
    NetDriverState *nd;
170
    uint32_t leptr;
171
    uint16_t addr;
172
    uint16_t regs[LE_MAXREG];
173
    uint8_t phys[6]; /* mac address */
174
    int irq;
175
    LEDMAState *ledma;
176
} LANCEState;
177

  
178
static int lance_io_memory;
179

  
180
static unsigned int rxptr, txptr;
181

  
182
static void lance_send(void *opaque);
183

  
184
static void lance_reset(LANCEState *s)
185
{
186
    memcpy(s->phys, s->nd->macaddr, 6);
187
    rxptr = 0;
188
    txptr = 0;
189
    s->regs[LE_CSR0] = LE_C0_STOP;
190
}
191

  
192
static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
193
{
194
    LANCEState *s = opaque;
195
    uint32_t saddr;
196

  
197
    saddr = addr - PHYS_JJ_LE;
198
    switch (saddr >> 1) {
199
    case LE_RDP:
200
	return s->regs[s->addr];
201
    case LE_RAP:
202
	return s->addr;
203
    default:
204
	break;
205
    }
206
    return 0;
207
}
208

  
209
static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
210
{
211
    LANCEState *s = opaque;
212
    uint32_t saddr;
213
    uint16_t clear, reg;
214

  
215
    saddr = addr - PHYS_JJ_LE;
216
    switch (saddr >> 1) {
217
    case LE_RDP:
218
	switch(s->addr) {
219
	case LE_CSR0:
220
	    if (val & LE_C0_STOP) {
221
		s->regs[LE_CSR0] = LE_C0_STOP;
222
		break;
223
	    }
224

  
225
	    reg = s->regs[LE_CSR0];
226

  
227
	    // 1 = clear for some bits
228
	    reg &= ~(val & 0x7f00);
229

  
230
	    // generated bits
231
	    reg &= ~(LE_C0_ERR | LE_C0_INTR);
232
	    if (reg & 0x7100)
233
		reg |= LE_C0_ERR;
234
	    if (reg & 0x7f00)
235
		reg |= LE_C0_INTR;
236

  
237
	    // direct bit
238
	    reg &= ~LE_C0_INEA;
239
	    reg |= val & LE_C0_INEA;
240

  
241
	    // exclusive bits
242
	    if (val & LE_C0_INIT) {
243
		reg |= LE_C0_IDON | LE_C0_INIT;
244
		reg &= ~LE_C0_STOP;
245
	    }
246
	    else if (val & LE_C0_STRT) {
247
		reg |= LE_C0_STRT | LE_C0_RXON | LE_C0_TXON;
248
		reg &= ~LE_C0_STOP;
249
	    }
250

  
251
	    s->regs[LE_CSR0] = reg;
252

  
253
	    // trigger bits
254
	    //if (val & LE_C0_TDMD)
255

  
256
	    if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
257
		pic_set_irq(s->irq, 1);
258
	    break;
259
	case LE_CSR1:
260
	    s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
261
	    s->regs[s->addr] = val;
262
	    break;
263
	case LE_CSR2:
264
	    s->leptr = (s->leptr & 0xffff) | ((val & 0xffff) << 16);
265
	    s->regs[s->addr] = val;
266
	    break;
267
	case LE_CSR3:
268
	    s->regs[s->addr] = val;
269
	    break;
270
	}
271
	break;
272
    case LE_RAP:
273
	if (val < LE_MAXREG)
274
	    s->addr = val;
275
	break;
276
    default:
277
	break;
278
    }
279
    lance_send(s);
280
}
281

  
282
static CPUReadMemoryFunc *lance_mem_read[3] = {
283
    lance_mem_readw,
284
    lance_mem_readw,
285
    lance_mem_readw,
286
};
287

  
288
static CPUWriteMemoryFunc *lance_mem_write[3] = {
289
    lance_mem_writew,
290
    lance_mem_writew,
291
    lance_mem_writew,
292
};
293

  
294

  
295
/* return the max buffer size if the LANCE can receive more data */
296
static int lance_can_receive(void *opaque)
297
{
298
    LANCEState *s = opaque;
299
    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
300
    struct lance_init_block *ib;
301
    int i;
302
    uint16_t temp;
303

  
304
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
305
	return 0;
306

  
307
    ib = (void *) iommu_translate(dmaptr);
308

  
309
    for (i = 0; i < RX_RING_SIZE; i++) {
310
	cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
311
	temp &= 0xff;
312
	if (temp == (LE_R1_OWN)) {
313
#ifdef DEBUG_LANCE
314
	    fprintf(stderr, "lance: can receive %d\n", RX_BUFF_SIZE);
315
#endif
316
	    return RX_BUFF_SIZE;
317
	}
318
    }
319
#ifdef DEBUG_LANCE
320
    fprintf(stderr, "lance: cannot receive\n");
321
#endif
322
    return 0;
323
}
324

  
325
#define MIN_BUF_SIZE 60
326

  
327
static void lance_receive(void *opaque, const uint8_t *buf, int size)
328
{
329
    LANCEState *s = opaque;
330
    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
331
    struct lance_init_block *ib;
332
    unsigned int i, old_rxptr, j;
333
    uint16_t temp;
334

  
335
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
336
	return;
337

  
338
    ib = (void *) iommu_translate(dmaptr);
339

  
340
    old_rxptr = rxptr;
341
    for (i = rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
342
	cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
343
	if (temp == (LE_R1_OWN)) {
344
	    rxptr = (rxptr + 1) & RX_RING_MOD_MASK;
345
	    temp = size;
346
	    bswap16s(&temp);
347
	    cpu_physical_memory_write(&ib->brx_ring[i].mblength, (void *) &temp, 2);
348
#if 0
349
	    cpu_physical_memory_write(&ib->rx_buf[i], buf, size);
350
#else
351
	    for (j = 0; j < size; j++) {
352
		cpu_physical_memory_write(((void *)&ib->rx_buf[i]) + j, &buf[j], 1);
353
	    }
354
#endif
355
	    temp = LE_R1_POK;
356
	    cpu_physical_memory_write(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
357
	    s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
358
	    if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
359
		pic_set_irq(s->irq, 1);
360
#ifdef DEBUG_LANCE
361
	    fprintf(stderr, "lance: got packet, len %d\n", size);
362
#endif
363
	    return;
364
	}
365
    }
366
}
367

  
368
static void lance_send(void *opaque)
369
{
370
    LANCEState *s = opaque;
371
    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
372
    struct lance_init_block *ib;
373
    unsigned int i, old_txptr, j;
374
    uint16_t temp;
375
    char pkt_buf[PKT_BUF_SZ];
376

  
377
    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
378
	return;
379

  
380
    ib = (void *) iommu_translate(dmaptr);
381

  
382
    old_txptr = txptr;
383
    for (i = txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
384
	cpu_physical_memory_read(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
385
	if (temp == (LE_T1_POK|LE_T1_OWN)) {
386
	    cpu_physical_memory_read(&ib->btx_ring[i].length, (void *) &temp, 2);
387
	    bswap16s(&temp);
388
	    temp = (~temp) + 1;
389
#if 0
390
	    cpu_physical_memory_read(&ib->tx_buf[i], pkt_buf, temp);
391
#else
392
	    for (j = 0; j < temp; j++) {
393
		cpu_physical_memory_read(((void *)&ib->tx_buf[i]) + j, &pkt_buf[j], 1);
394
	    }
395
#endif
396

  
397
#ifdef DEBUG_LANCE
398
	    fprintf(stderr, "lance: sending packet, len %d\n", temp);
399
#endif
400
	    qemu_send_packet(s->nd, pkt_buf, temp);
401
	    temp = LE_T1_POK;
402
	    cpu_physical_memory_write(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
403
	    txptr = (txptr + 1) & TX_RING_MOD_MASK;
404
	    s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
405
	}
406
    }
407
}
408

  
409
static int ledma_io_memory;
410

  
411
static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
412
{
413
    LEDMAState *s = opaque;
414
    uint32_t saddr;
415

  
416
    saddr = (addr - PHYS_JJ_LEDMA) >> 2;
417
    if (saddr < LEDMA_REGS)
418
	return s->regs[saddr];
419
    else
420
	return 0;
421
}
422

  
423
static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
424
{
425
    LEDMAState *s = opaque;
426
    uint32_t saddr;
427

  
428
    saddr = (addr - PHYS_JJ_LEDMA) >> 2;
429
    if (saddr < LEDMA_REGS)
430
	s->regs[saddr] = val;
431
}
432

  
433
static CPUReadMemoryFunc *ledma_mem_read[3] = {
434
    ledma_mem_readl,
435
    ledma_mem_readl,
436
    ledma_mem_readl,
437
};
438

  
439
static CPUWriteMemoryFunc *ledma_mem_write[3] = {
440
    ledma_mem_writel,
441
    ledma_mem_writel,
442
    ledma_mem_writel,
443
};
444

  
445
void lance_init(NetDriverState *nd, int irq)
446
{
447
    LANCEState *s;
448
    LEDMAState *led;
449

  
450
    s = qemu_mallocz(sizeof(LANCEState));
451
    if (!s)
452
        return;
453

  
454
    lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
455
    cpu_register_physical_memory(PHYS_JJ_LE, 8,
456
                                 lance_io_memory);
457
    led = qemu_mallocz(sizeof(LEDMAState));
458
    if (!led)
459
        return;
460

  
461
    ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led);
462
    cpu_register_physical_memory(PHYS_JJ_LEDMA, 16,
463
                                 ledma_io_memory);
464

  
465
    s->nd = nd;
466
    s->ledma = led;
467
    s->irq = irq;
468

  
469
    lance_reset(s);
470
    qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
471
}
472

  
b/hw/m48t08.c
1
/*
2
 * QEMU M48T08 NVRAM emulation for Sparc platform
3
 * 
4
 * Copyright (c) 2003-2004 Jocelyn Mayer
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25
#include "m48t08.h"
26

  
27
//#define DEBUG_NVRAM
28

  
29
#if defined(DEBUG_NVRAM)
30
#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
31
#else
32
#define NVRAM_PRINTF(fmt, args...) do { } while (0)
33
#endif
34

  
35
#define NVRAM_MAX_MEM 0xfff0
36

  
37
struct m48t08_t {
38
    /* Hardware parameters */
39
    int mem_index;
40
    uint32_t mem_base;
41
    uint16_t size;
42
    /* RTC management */
43
    time_t   time_offset;
44
    time_t   stop_time;
45
    /* NVRAM storage */
46
    uint8_t  lock;
47
    uint16_t addr;
48
    uint8_t *buffer;
49
};
50

  
51
/* Fake timer functions */
52
/* Generic helpers for BCD */
53
static inline uint8_t toBCD (uint8_t value)
54
{
55
    return (((value / 10) % 10) << 4) | (value % 10);
56
}
57

  
58
static inline uint8_t fromBCD (uint8_t BCD)
59
{
60
    return ((BCD >> 4) * 10) + (BCD & 0x0F);
61
}
62

  
63
/* RTC management helpers */
64
static void get_time (m48t08_t *NVRAM, struct tm *tm)
65
{
66
    time_t t;
67

  
68
    t = time(NULL) + NVRAM->time_offset;
69
#ifdef _WIN32
70
    memcpy(tm,localtime(&t),sizeof(*tm));
71
#else
72
    localtime_r (&t, tm) ;
73
#endif
74
}
75

  
76
static void set_time (m48t08_t *NVRAM, struct tm *tm)
77
{
78
    time_t now, new_time;
79
    
80
    new_time = mktime(tm);
81
    now = time(NULL);
82
    NVRAM->time_offset = new_time - now;
83
}
84

  
85
/* Direct access to NVRAM */
86
void m48t08_write (m48t08_t *NVRAM, uint32_t val)
87
{
88
    struct tm tm;
89
    int tmp;
90

  
91
    if (NVRAM->addr > NVRAM_MAX_MEM && NVRAM->addr < 0x2000)
92
	NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
93
    switch (NVRAM->addr) {
94
    case 0x1FF8:
95
        /* control */
96
	NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
97
        break;
98
    case 0x1FF9:
99
        /* seconds (BCD) */
100
	tmp = fromBCD(val & 0x7F);
101
	if (tmp >= 0 && tmp <= 59) {
102
	    get_time(NVRAM, &tm);
103
	    tm.tm_sec = tmp;
104
	    set_time(NVRAM, &tm);
105
	}
106
	if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
107
	    if (val & 0x80) {
108
		NVRAM->stop_time = time(NULL);
109
	    } else {
110
		NVRAM->time_offset += NVRAM->stop_time - time(NULL);
111
		NVRAM->stop_time = 0;
112
	    }
113
	}
114
	NVRAM->buffer[0x1FF9] = val & 0x80;
115
        break;
116
    case 0x1FFA:
117
        /* minutes (BCD) */
118
	tmp = fromBCD(val & 0x7F);
119
	if (tmp >= 0 && tmp <= 59) {
120
	    get_time(NVRAM, &tm);
121
	    tm.tm_min = tmp;
122
	    set_time(NVRAM, &tm);
123
	}
124
        break;
125
    case 0x1FFB:
126
        /* hours (BCD) */
127
	tmp = fromBCD(val & 0x3F);
128
	if (tmp >= 0 && tmp <= 23) {
129
	    get_time(NVRAM, &tm);
130
	    tm.tm_hour = tmp;
131
	    set_time(NVRAM, &tm);
132
	}
133
        break;
134
    case 0x1FFC:
135
        /* day of the week / century */
136
	tmp = fromBCD(val & 0x07);
137
	get_time(NVRAM, &tm);
138
	tm.tm_wday = tmp;
139
	set_time(NVRAM, &tm);
140
        NVRAM->buffer[0x1FFC] = val & 0x40;
141
        break;
142
    case 0x1FFD:
143
        /* date */
144
	tmp = fromBCD(val & 0x1F);
145
	if (tmp != 0) {
146
	    get_time(NVRAM, &tm);
147
	    tm.tm_mday = tmp;
148
	    set_time(NVRAM, &tm);
149
	}
150
        break;
151
    case 0x1FFE:
152
        /* month */
153
	tmp = fromBCD(val & 0x1F);
154
	if (tmp >= 1 && tmp <= 12) {
155
	    get_time(NVRAM, &tm);
156
	    tm.tm_mon = tmp - 1;
157
	    set_time(NVRAM, &tm);
158
	}
159
        break;
160
    case 0x1FFF:
161
        /* year */
162
	tmp = fromBCD(val);
163
	if (tmp >= 0 && tmp <= 99) {
164
	    get_time(NVRAM, &tm);
165
	    tm.tm_year = fromBCD(val);
166
	    set_time(NVRAM, &tm);
167
	}
168
        break;
169
    default:
170
        /* Check lock registers state */
171
        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
172
            break;
173
        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
174
            break;
175
        if (NVRAM->addr < NVRAM_MAX_MEM ||
176
	    (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
177
            NVRAM->buffer[NVRAM->addr] = val & 0xFF;
178
	}
179
        break;
180
    }
181
}
182

  
183
uint32_t m48t08_read (m48t08_t *NVRAM)
184
{
185
    struct tm tm;
186
    uint32_t retval = 0xFF;
187

  
188
    switch (NVRAM->addr) {
189
    case 0x1FF8:
190
        /* control */
191
	goto do_read;
192
    case 0x1FF9:
193
        /* seconds (BCD) */
194
        get_time(NVRAM, &tm);
195
        retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
196
        break;
197
    case 0x1FFA:
198
        /* minutes (BCD) */
199
        get_time(NVRAM, &tm);
200
        retval = toBCD(tm.tm_min);
201
        break;
202
    case 0x1FFB:
203
        /* hours (BCD) */
204
        get_time(NVRAM, &tm);
205
        retval = toBCD(tm.tm_hour);
206
        break;
207
    case 0x1FFC:
208
        /* day of the week / century */
209
        get_time(NVRAM, &tm);
210
        retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
211
        break;
212
    case 0x1FFD:
213
        /* date */
214
        get_time(NVRAM, &tm);
215
        retval = toBCD(tm.tm_mday);
216
        break;
217
    case 0x1FFE:
218
        /* month */
219
        get_time(NVRAM, &tm);
220
        retval = toBCD(tm.tm_mon + 1);
221
        break;
222
    case 0x1FFF:
223
        /* year */
224
        get_time(NVRAM, &tm);
225
        retval = toBCD(tm.tm_year);
226
        break;
227
    default:
228
        /* Check lock registers state */
229
        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
230
            break;
231
        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
232
            break;
233
        if (NVRAM->addr < NVRAM_MAX_MEM ||
234
	    (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
235
	do_read:
236
            retval = NVRAM->buffer[NVRAM->addr];
237
	}
238
        break;
239
    }
240
    if (NVRAM->addr > NVRAM_MAX_MEM + 1 && NVRAM->addr < 0x2000)
241
	NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
242

  
243
    return retval;
244
}
245

  
246
void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr)
247
{
248
    NVRAM->addr = addr;
249
}
250

  
251
void m48t08_toggle_lock (m48t08_t *NVRAM, int lock)
252
{
253
    NVRAM->lock ^= 1 << lock;
254
}
255

  
256
static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
257
{
258
    m48t08_t *NVRAM = opaque;
259
    
260
    addr -= NVRAM->mem_base;
261
    if (addr < NVRAM_MAX_MEM)
262
        NVRAM->buffer[addr] = value;
263
}
264

  
265
static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
266
{
267
    m48t08_t *NVRAM = opaque;
268
    
269
    addr -= NVRAM->mem_base;
270
    if (addr < NVRAM_MAX_MEM) {
271
        NVRAM->buffer[addr] = value >> 8;
272
        NVRAM->buffer[addr + 1] = value;
273
    }
274
}
275

  
276
static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
277
{
278
    m48t08_t *NVRAM = opaque;
279
    
280
    addr -= NVRAM->mem_base;
281
    if (addr < NVRAM_MAX_MEM) {
282
        NVRAM->buffer[addr] = value >> 24;
283
        NVRAM->buffer[addr + 1] = value >> 16;
284
        NVRAM->buffer[addr + 2] = value >> 8;
285
        NVRAM->buffer[addr + 3] = value;
286
    }
287
}
288

  
289
static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
290
{
291
    m48t08_t *NVRAM = opaque;
292
    uint32_t retval = 0;
293
    
294
    addr -= NVRAM->mem_base;
295
    if (addr < NVRAM_MAX_MEM)
296
        retval = NVRAM->buffer[addr];
297

  
298
    return retval;
299
}
300

  
301
static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
302
{
303
    m48t08_t *NVRAM = opaque;
304
    uint32_t retval = 0;
305
    
306
    addr -= NVRAM->mem_base;
307
    if (addr < NVRAM_MAX_MEM) {
308
        retval = NVRAM->buffer[addr] << 8;
309
        retval |= NVRAM->buffer[addr + 1];
310
    }
311

  
312
    return retval;
313
}
314

  
315
static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
316
{
317
    m48t08_t *NVRAM = opaque;
318
    uint32_t retval = 0;
319
    
320
    addr -= NVRAM->mem_base;
321
    if (addr < NVRAM_MAX_MEM) {
322
        retval = NVRAM->buffer[addr] << 24;
323
        retval |= NVRAM->buffer[addr + 1] << 16;
324
        retval |= NVRAM->buffer[addr + 2] << 8;
325
        retval |= NVRAM->buffer[addr + 3];
326
    }
327

  
328
    return retval;
329
}
330

  
331
static CPUWriteMemoryFunc *nvram_write[] = {
332
    &nvram_writeb,
333
    &nvram_writew,
334
    &nvram_writel,
335
};
336

  
337
static CPUReadMemoryFunc *nvram_read[] = {
338
    &nvram_readb,
339
    &nvram_readw,
340
    &nvram_readl,
341
};
342

  
343
/* Initialisation routine */
344
m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size)
345
{
346
    m48t08_t *s;
347
    int i;
348
    unsigned char tmp = 0;
349

  
350
    s = qemu_mallocz(sizeof(m48t08_t));
351
    if (!s)
352
	return NULL;
353
    s->buffer = qemu_mallocz(size);
354
    if (!s->buffer) {
355
        qemu_free(s);
356
        return NULL;
357
    }
358
    s->size = size;
359
    s->mem_base = mem_base;
360
    s->addr = 0;
361
    if (mem_base != 0) {
362
        s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
363
        cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
364
    }
365
    s->lock = 0;
366

  
367
    i = 0x1fd8;
368
    s->buffer[i++] = 0x01;
369
    s->buffer[i++] = 0x80; /* Sun4m OBP */
370
    /* XXX: Ethernet address, etc */
371

  
372
    /* Calculate checksum */
373
    for (i = 0x1fd8; i < 0x1fe7; i++) {
374
	tmp ^= s->buffer[i];
375
    }
376
    s->buffer[0x1fe7] = tmp;
377
    return s;
378
}
379

  
380
#if 0
381
struct idprom
382
{
383
        unsigned char   id_format;      /* Format identifier (always 0x01) */
384
        unsigned char   id_machtype;    /* Machine type */
385
        unsigned char   id_ethaddr[6];  /* Hardware ethernet address */
386
        long            id_date;        /* Date of manufacture */
387
        unsigned int    id_sernum:24;   /* Unique serial number */
388
        unsigned char   id_cksum;       /* Checksum - xor of the data bytes */
389
        unsigned char   reserved[16];
390
};
391
#endif
b/hw/m48t08.h
1
#if !defined (__M48T08_H__)
2
#define __M48T08_H__
3

  
4
typedef struct m48t08_t m48t08_t;
5

  
6
void m48t08_write (m48t08_t *NVRAM, uint32_t val);
7
uint32_t m48t08_read (m48t08_t *NVRAM);
8
void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr);
9
void m48t08_toggle_lock (m48t08_t *NVRAM, int lock);
10
m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size);
11

  
12
#endif /* !defined (__M48T08_H__) */
b/hw/magic-load.c
1
/* This is the Linux kernel elf-loading code, ported into user space */
2
#include "vl.h"
3
#include "disas.h"
4

  
5
/* XXX: this code is not used as it is under the GPL license. Please
6
   remove or recode it */
7
//#define USE_ELF_LOADER
8

  
9
#ifdef USE_ELF_LOADER
10
/* should probably go in elf.h */
11
#ifndef ELIBBAD
12
#define ELIBBAD 80
13
#endif
14

  
15

  
16
#define ELF_START_MMAP 0x80000000
17

  
18
#define elf_check_arch(x) ( (x) == EM_SPARC )
19

  
20
#define ELF_CLASS   ELFCLASS32
21
#define ELF_DATA    ELFDATA2MSB
22
#define ELF_ARCH    EM_SPARC
23

  
24
#include "elf.h"
25

  
26
/*
27
 * This structure is used to hold the arguments that are 
28
 * used when loading binaries.
29
 */
30
struct linux_binprm {
31
        char buf[128];
32
	int fd;
33
};
34

  
35
#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
36
#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
37
#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
38

  
39
#ifdef BSWAP_NEEDED
40
static void bswap_ehdr(Elf32_Ehdr *ehdr)
41
{
42
    bswap16s(&ehdr->e_type);			/* Object file type */
43
    bswap16s(&ehdr->e_machine);		/* Architecture */
44
    bswap32s(&ehdr->e_version);		/* Object file version */
45
    bswap32s(&ehdr->e_entry);		/* Entry point virtual address */
46
    bswap32s(&ehdr->e_phoff);		/* Program header table file offset */
47
    bswap32s(&ehdr->e_shoff);		/* Section header table file offset */
48
    bswap32s(&ehdr->e_flags);		/* Processor-specific flags */
49
    bswap16s(&ehdr->e_ehsize);		/* ELF header size in bytes */
50
    bswap16s(&ehdr->e_phentsize);		/* Program header table entry size */
51
    bswap16s(&ehdr->e_phnum);		/* Program header table entry count */
52
    bswap16s(&ehdr->e_shentsize);		/* Section header table entry size */
53
    bswap16s(&ehdr->e_shnum);		/* Section header table entry count */
54
    bswap16s(&ehdr->e_shstrndx);		/* Section header string table index */
55
}
56

  
57
static void bswap_phdr(Elf32_Phdr *phdr)
58
{
59
    bswap32s(&phdr->p_type);			/* Segment type */
60
    bswap32s(&phdr->p_offset);		/* Segment file offset */
61
    bswap32s(&phdr->p_vaddr);		/* Segment virtual address */
62
    bswap32s(&phdr->p_paddr);		/* Segment physical address */
63
    bswap32s(&phdr->p_filesz);		/* Segment size in file */
64
    bswap32s(&phdr->p_memsz);		/* Segment size in memory */
65
    bswap32s(&phdr->p_flags);		/* Segment flags */
66
    bswap32s(&phdr->p_align);		/* Segment alignment */
67
}
68

  
69
static void bswap_shdr(Elf32_Shdr *shdr)
70
{
71
    bswap32s(&shdr->sh_name);
72
    bswap32s(&shdr->sh_type);
73
    bswap32s(&shdr->sh_flags);
74
    bswap32s(&shdr->sh_addr);
75
    bswap32s(&shdr->sh_offset);
76
    bswap32s(&shdr->sh_size);
77
    bswap32s(&shdr->sh_link);
78
    bswap32s(&shdr->sh_info);
79
    bswap32s(&shdr->sh_addralign);
80
    bswap32s(&shdr->sh_entsize);
81
}
82

  
83
static void bswap_sym(Elf32_Sym *sym)
84
{
85
    bswap32s(&sym->st_name);
86
    bswap32s(&sym->st_value);
87
    bswap32s(&sym->st_size);
88
    bswap16s(&sym->st_shndx);
89
}
90
#endif
91

  
92
static int prepare_binprm(struct linux_binprm *bprm)
93
{
94
    int retval;
95

  
96
    memset(bprm->buf, 0, sizeof(bprm->buf));
97
    retval = lseek(bprm->fd, 0L, SEEK_SET);
98
    if(retval >= 0) {
99
        retval = read(bprm->fd, bprm->buf, 128);
100
    }
101
    if(retval < 0) {
102
	perror("prepare_binprm");
103
	exit(-1);
104
	/* return(-errno); */
105
    }
106
    else {
107
	return(retval);
108
    }
109
}
110

  
111
/* Best attempt to load symbols from this ELF object. */
112
static void load_symbols(struct elfhdr *hdr, int fd)
113
{
114
    unsigned int i;
115
    struct elf_shdr sechdr, symtab, strtab;
116
    char *strings;
117

  
118
    lseek(fd, hdr->e_shoff, SEEK_SET);
119
    for (i = 0; i < hdr->e_shnum; i++) {
120
	if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr))
121
	    return;
122
#ifdef BSWAP_NEEDED
123
	bswap_shdr(&sechdr);
124
#endif
125
	if (sechdr.sh_type == SHT_SYMTAB) {
126
	    symtab = sechdr;
127
	    lseek(fd, hdr->e_shoff
128
		  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET);
129
	    if (read(fd, &strtab, sizeof(strtab))
130
		!= sizeof(strtab))
131
		return;
132
#ifdef BSWAP_NEEDED
133
	    bswap_shdr(&strtab);
134
#endif
135
	    goto found;
136
	}
137
    }
138
    return; /* Shouldn't happen... */
139

  
140
 found:
141
    /* Now know where the strtab and symtab are.  Snarf them. */
142
    disas_symtab = qemu_malloc(symtab.sh_size);
143
    disas_strtab = strings = qemu_malloc(strtab.sh_size);
144
    if (!disas_symtab || !disas_strtab)
145
	return;
146
	
147
    lseek(fd, symtab.sh_offset, SEEK_SET);
148
    if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size)
149
	return;
150

  
151
#ifdef BSWAP_NEEDED
152
    for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
153
	bswap_sym(disas_symtab + sizeof(struct elf_sym)*i);
154
#endif
155

  
156
    lseek(fd, strtab.sh_offset, SEEK_SET);
157
    if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
158
	return;
159
    disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
160
}
161

  
162
static int load_elf_binary(struct linux_binprm * bprm, uint8_t *addr)
163
{
164
    struct elfhdr elf_ex;
165
    unsigned long startaddr = addr;
166
    int i;
167
    struct elf_phdr * elf_ppnt;
168
    struct elf_phdr *elf_phdata;
169
    int retval;
170

  
171
    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */
172
#ifdef BSWAP_NEEDED
173
    bswap_ehdr(&elf_ex);
174
#endif
175

  
176
    if (elf_ex.e_ident[0] != 0x7f ||
177
	strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) {
178
	return  -ENOEXEC;
179
    }
180

  
181
    /* First of all, some simple consistency checks */
182
    if (! elf_check_arch(elf_ex.e_machine)) {
183
	return -ENOEXEC;
184
    }
185

  
186
    /* Now read in all of the header information */
187
    elf_phdata = (struct elf_phdr *)qemu_malloc(elf_ex.e_phentsize*elf_ex.e_phnum);
188
    if (elf_phdata == NULL) {
189
	return -ENOMEM;
190
    }
191

  
192
    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET);
193
    if(retval > 0) {
194
	retval = read(bprm->fd, (char *) elf_phdata, 
195
				elf_ex.e_phentsize * elf_ex.e_phnum);
196
    }
197

  
198
    if (retval < 0) {
199
	perror("load_elf_binary");
200
	exit(-1);
201
	qemu_free (elf_phdata);
202
	return -errno;
203
    }
204

  
205
#ifdef BSWAP_NEEDED
206
    elf_ppnt = elf_phdata;
207
    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) {
208
        bswap_phdr(elf_ppnt);
209
    }
210
#endif
211
    elf_ppnt = elf_phdata;
212

  
213
    /* Now we do a little grungy work by mmaping the ELF image into
214
     * the correct location in memory.  At this point, we assume that
215
     * the image should be loaded at fixed address, not at a variable
216
     * address.
217
     */
218

  
219
    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) {
220
        unsigned long error, offset, len;
221
        
222
	if (elf_ppnt->p_type != PT_LOAD)
223
            continue;
224
#if 0        
225
        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr),
226
                            elf_prot,
227
                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
228
                            bprm->fd,
229
                            (elf_ppnt->p_offset - 
230
                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
231
#endif
232
	//offset = elf_ppnt->p_offset - TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
233
	offset = 0x4000;
234
	lseek(bprm->fd, offset, SEEK_SET);
235
	len = elf_ppnt->p_filesz + TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr);
236
	error = read(bprm->fd, addr, len); 
237

  
238
        if (error == -1) {
239
            perror("mmap");
240
            exit(-1);
241
        }
242
	addr += len;
243
    }
244

  
245
    qemu_free(elf_phdata);
246

  
247
    load_symbols(&elf_ex, bprm->fd);
248

  
249
    return addr-startaddr;
250
}
251

  
252
int elf_exec(const char * filename, uint8_t *addr)
253
{
254
        struct linux_binprm bprm;
255
        int retval;
256

  
257
        retval = open(filename, O_RDONLY);
258
        if (retval < 0)
259
            return retval;
260
        bprm.fd = retval;
261

  
262
        retval = prepare_binprm(&bprm);
263

  
264
        if(retval>=0) {
265
	    retval = load_elf_binary(&bprm, addr);
266
	}
267
	return retval;
268
}
269
#endif
270

  
271
int load_kernel(const char *filename, uint8_t *addr)
272
{
273
    int fd, size;
274

  
275
    fd = open(filename, O_RDONLY | O_BINARY);
276
    if (fd < 0)
277
        return -1;
278
    /* load 32 bit code */
279
    size = read(fd, addr, 16 * 1024 * 1024);
280
    if (size < 0)
281
        goto fail;
282
    close(fd);
283
    return size;
284
 fail:
285
    close(fd);
286
    return -1;
287
}
288

  
289
static char saved_kfn[1024];
290
static uint32_t saved_addr;
291
static int magic_state;
292

  
293
static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)
294
{
295
    int ret;
296

  
297
    if (magic_state == 0) {
298
#ifdef USE_ELF_LOADER
299
        ret = elf_exec(saved_kfn, saved_addr);
300
#else
301
        ret = load_kernel(saved_kfn, (uint8_t *)saved_addr);
302
#endif
303
        if (ret < 0) {
304
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
305
                    saved_kfn);
306
        }
307
	magic_state = 1; /* No more magic */
308
	tb_flush();
309
    }
310
    return ret;
311
}
312

  
313
static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
314
{
315
}
316

  
317

  
318
static CPUReadMemoryFunc *magic_mem_read[3] = {
319
    magic_mem_readl,
320
    magic_mem_readl,
321
    magic_mem_readl,
322
};
323

  
324
static CPUWriteMemoryFunc *magic_mem_write[3] = {
325
    magic_mem_writel,
326
    magic_mem_writel,
327
    magic_mem_writel,
328
};
329

  
330
void magic_init(const char *kfn, int kloadaddr)
331
{
332
    int magic_io_memory;
333

  
334
    strcpy(saved_kfn, kfn);
335
    saved_addr = kloadaddr;
336
    magic_state = 0;
337
    magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, 0);
338
    cpu_register_physical_memory(0x20000000, 4,
339
                                 magic_io_memory);
340
}
341

  
b/hw/sched.c
1
/*
2
 * QEMU interrupt controller & timer emulation
3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff