Commit 8d5f07fa3bd3433e779d13eb1cda4fbb07acb67f
1 parent
023fcb95
sparc merge (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1098 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
23 changed files
with
484 additions
and
584 deletions
Makefile
1 | -include config-host.mak | |
1 | +-include config-host.mak | |
2 | 2 | |
3 | 3 | CFLAGS=-Wall -O2 -g -fno-strict-aliasing |
4 | 4 | ifdef CONFIG_DARWIN |
... | ... | @@ -14,8 +14,9 @@ TOOLS=qemu-img |
14 | 14 | ifdef CONFIG_STATIC |
15 | 15 | LDFLAGS+=-static |
16 | 16 | endif |
17 | +DOCS=qemu-doc.html qemu-tech.html qemu.1 | |
17 | 18 | |
18 | -all: dyngen$(EXESUF) $(TOOLS) qemu-doc.html qemu-tech.html qemu.1 | |
19 | +all: dyngen$(EXESUF) $(TOOLS) $(DOCS) | |
19 | 20 | for d in $(TARGET_DIRS); do \ |
20 | 21 | $(MAKE) -C $$d $@ || exit 1 ; \ |
21 | 22 | done |
... | ... | @@ -29,14 +30,14 @@ dyngen$(EXESUF): dyngen.c |
29 | 30 | clean: |
30 | 31 | # avoid old build problems by removing potentially incorrect old files |
31 | 32 | rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h |
32 | - rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod | |
33 | + rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~ | |
33 | 34 | $(MAKE) -C tests clean |
34 | 35 | for d in $(TARGET_DIRS); do \ |
35 | 36 | $(MAKE) -C $$d $@ || exit 1 ; \ |
36 | 37 | done |
37 | 38 | |
38 | 39 | distclean: clean |
39 | - rm -f config-host.mak config-host.h | |
40 | + rm -f config-host.mak config-host.h $(DOCS) | |
40 | 41 | for d in $(TARGET_DIRS); do \ |
41 | 42 | rm -rf $$d || exit 1 ; \ |
42 | 43 | done |
... | ... | @@ -50,6 +51,7 @@ endif |
50 | 51 | install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \ |
51 | 52 | pc-bios/vgabios-cirrus.bin \ |
52 | 53 | pc-bios/ppc_rom.bin \ |
54 | + pc-bios/proll.bin \ | |
53 | 55 | pc-bios/linux_boot.bin "$(datadir)" |
54 | 56 | mkdir -p "$(docdir)" |
55 | 57 | install -m 644 qemu-doc.html qemu-tech.html "$(docdir)" |
... | ... | @@ -99,6 +101,7 @@ tarbin: |
99 | 101 | $(datadir)/vgabios.bin \ |
100 | 102 | $(datadir)/vgabios-cirrus.bin \ |
101 | 103 | $(datadir)/ppc_rom.bin \ |
104 | + $(datadir)/proll.bin \ | |
102 | 105 | $(datadir)/linux_boot.bin \ |
103 | 106 | $(docdir)/qemu-doc.html \ |
104 | 107 | $(docdir)/qemu-tech.html \ | ... | ... |
Makefile.target
... | ... | @@ -279,7 +279,7 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o |
279 | 279 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o |
280 | 280 | endif |
281 | 281 | ifeq ($(TARGET_ARCH), sparc) |
282 | -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o | |
282 | +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o timer.o | |
283 | 283 | endif |
284 | 284 | ifdef CONFIG_GDBSTUB |
285 | 285 | VL_OBJS+=gdbstub.o | ... | ... |
gdbstub.c
... | ... | @@ -387,6 +387,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) |
387 | 387 | env->eip = addr; |
388 | 388 | #elif defined (TARGET_PPC) |
389 | 389 | env->nip = addr; |
390 | +#elif defined (TARGET_SPARC) | |
391 | + env->pc = addr; | |
392 | + env->npc = addr + 4; | |
390 | 393 | #endif |
391 | 394 | } |
392 | 395 | vm_start(); |
... | ... | @@ -398,6 +401,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) |
398 | 401 | env->eip = addr; |
399 | 402 | #elif defined (TARGET_PPC) |
400 | 403 | env->nip = addr; |
404 | +#elif defined (TARGET_SPARC) | |
405 | + env->pc = addr; | |
406 | + env->npc = addr + 4; | |
401 | 407 | #endif |
402 | 408 | } |
403 | 409 | cpu_single_step(env, 1); | ... | ... |
hw/iommu.c
... | ... | @@ -107,29 +107,24 @@ struct iommu_regs { |
107 | 107 | #define IOPTE_VALID 0x00000002 /* IOPTE is valid */ |
108 | 108 | #define IOPTE_WAZ 0x00000001 /* Write as zeros */ |
109 | 109 | |
110 | -#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ | |
111 | 110 | #define PAGE_SHIFT 12 |
112 | 111 | #define PAGE_SIZE (1 << PAGE_SHIFT) |
113 | 112 | #define PAGE_MASK (PAGE_SIZE - 1) |
114 | 113 | |
115 | 114 | typedef struct IOMMUState { |
115 | + uint32_t addr; | |
116 | 116 | uint32_t regs[sizeof(struct iommu_regs)]; |
117 | + uint32_t iostart; | |
117 | 118 | } IOMMUState; |
118 | 119 | |
119 | 120 | static IOMMUState *ps; |
120 | 121 | |
121 | -static int iommu_io_memory; | |
122 | - | |
123 | -static void iommu_reset(IOMMUState *s) | |
124 | -{ | |
125 | -} | |
126 | - | |
127 | 122 | static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) |
128 | 123 | { |
129 | 124 | IOMMUState *s = opaque; |
130 | 125 | uint32_t saddr; |
131 | 126 | |
132 | - saddr = (addr - PHYS_JJ_IOMMU) >> 2; | |
127 | + saddr = (addr - s->addr) >> 2; | |
133 | 128 | switch (saddr) { |
134 | 129 | default: |
135 | 130 | return s->regs[saddr]; |
... | ... | @@ -143,8 +138,37 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
143 | 138 | IOMMUState *s = opaque; |
144 | 139 | uint32_t saddr; |
145 | 140 | |
146 | - saddr = (addr - PHYS_JJ_IOMMU) >> 2; | |
141 | + saddr = (addr - s->addr) >> 2; | |
147 | 142 | switch (saddr) { |
143 | + case 0: | |
144 | + switch (val & IOMMU_CTRL_RNGE) { | |
145 | + case IOMMU_RNGE_16MB: | |
146 | + s->iostart = 0xff000000; | |
147 | + break; | |
148 | + case IOMMU_RNGE_32MB: | |
149 | + s->iostart = 0xfe000000; | |
150 | + break; | |
151 | + case IOMMU_RNGE_64MB: | |
152 | + s->iostart = 0xfc000000; | |
153 | + break; | |
154 | + case IOMMU_RNGE_128MB: | |
155 | + s->iostart = 0xf8000000; | |
156 | + break; | |
157 | + case IOMMU_RNGE_256MB: | |
158 | + s->iostart = 0xf0000000; | |
159 | + break; | |
160 | + case IOMMU_RNGE_512MB: | |
161 | + s->iostart = 0xe0000000; | |
162 | + break; | |
163 | + case IOMMU_RNGE_1GB: | |
164 | + s->iostart = 0xc0000000; | |
165 | + break; | |
166 | + default: | |
167 | + case IOMMU_RNGE_2GB: | |
168 | + s->iostart = 0x80000000; | |
169 | + break; | |
170 | + } | |
171 | + /* Fall through */ | |
148 | 172 | default: |
149 | 173 | s->regs[saddr] = val; |
150 | 174 | break; |
... | ... | @@ -165,57 +189,30 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = { |
165 | 189 | |
166 | 190 | uint32_t iommu_translate(uint32_t addr) |
167 | 191 | { |
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 | - } | |
192 | + uint32_t *iopte = (void *)(ps->regs[1] << 4), pa; | |
197 | 193 | |
198 | - iopte += ((addr - iostart) >> PAGE_SHIFT); | |
194 | + iopte += ((addr - ps->iostart) >> PAGE_SHIFT); | |
199 | 195 | cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0); |
200 | 196 | bswap32s(&pa); |
201 | 197 | pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */ |
202 | - //return pa + PAGE_SIZE; | |
203 | 198 | return pa + (addr & PAGE_MASK); |
204 | 199 | } |
205 | 200 | |
206 | -void iommu_init() | |
201 | +void iommu_init(uint32_t addr) | |
207 | 202 | { |
208 | 203 | IOMMUState *s; |
204 | + int iommu_io_memory; | |
209 | 205 | |
210 | 206 | s = qemu_mallocz(sizeof(IOMMUState)); |
211 | 207 | if (!s) |
212 | 208 | return; |
213 | 209 | |
210 | + s->addr = addr; | |
211 | + | |
214 | 212 | 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), | |
213 | + cpu_register_physical_memory(addr, sizeof(struct iommu_regs), | |
216 | 214 | iommu_io_memory); |
217 | 215 | |
218 | - iommu_reset(s); | |
219 | 216 | ps = s; |
220 | 217 | } |
221 | 218 | ... | ... |
hw/lance.c
... | ... | @@ -24,11 +24,7 @@ |
24 | 24 | #include "vl.h" |
25 | 25 | |
26 | 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 */ | |
27 | +//#define DEBUG_LANCE | |
32 | 28 | |
33 | 29 | #ifndef LANCE_LOG_TX_BUFFERS |
34 | 30 | #define LANCE_LOG_TX_BUFFERS 4 |
... | ... | @@ -162,10 +158,12 @@ struct sparc_dma_registers { |
162 | 158 | #endif |
163 | 159 | |
164 | 160 | typedef struct LEDMAState { |
161 | + uint32_t addr; | |
165 | 162 | uint32_t regs[LEDMA_REGS]; |
166 | 163 | } LEDMAState; |
167 | 164 | |
168 | 165 | typedef struct LANCEState { |
166 | + uint32_t paddr; | |
169 | 167 | NetDriverState *nd; |
170 | 168 | uint32_t leptr; |
171 | 169 | uint16_t addr; |
... | ... | @@ -175,8 +173,6 @@ typedef struct LANCEState { |
175 | 173 | LEDMAState *ledma; |
176 | 174 | } LANCEState; |
177 | 175 | |
178 | -static int lance_io_memory; | |
179 | - | |
180 | 176 | static unsigned int rxptr, txptr; |
181 | 177 | |
182 | 178 | static void lance_send(void *opaque); |
... | ... | @@ -194,7 +190,7 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) |
194 | 190 | LANCEState *s = opaque; |
195 | 191 | uint32_t saddr; |
196 | 192 | |
197 | - saddr = addr - PHYS_JJ_LE; | |
193 | + saddr = addr - s->paddr; | |
198 | 194 | switch (saddr >> 1) { |
199 | 195 | case LE_RDP: |
200 | 196 | return s->regs[s->addr]; |
... | ... | @@ -210,9 +206,9 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val |
210 | 206 | { |
211 | 207 | LANCEState *s = opaque; |
212 | 208 | uint32_t saddr; |
213 | - uint16_t clear, reg; | |
209 | + uint16_t reg; | |
214 | 210 | |
215 | - saddr = addr - PHYS_JJ_LE; | |
211 | + saddr = addr - s->paddr; | |
216 | 212 | switch (saddr >> 1) { |
217 | 213 | case LE_RDP: |
218 | 214 | switch(s->addr) { |
... | ... | @@ -406,14 +402,12 @@ static void lance_send(void *opaque) |
406 | 402 | } |
407 | 403 | } |
408 | 404 | |
409 | -static int ledma_io_memory; | |
410 | - | |
411 | 405 | static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr) |
412 | 406 | { |
413 | 407 | LEDMAState *s = opaque; |
414 | 408 | uint32_t saddr; |
415 | 409 | |
416 | - saddr = (addr - PHYS_JJ_LEDMA) >> 2; | |
410 | + saddr = (addr - s->addr) >> 2; | |
417 | 411 | if (saddr < LEDMA_REGS) |
418 | 412 | return s->regs[saddr]; |
419 | 413 | else |
... | ... | @@ -425,7 +419,7 @@ static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val |
425 | 419 | LEDMAState *s = opaque; |
426 | 420 | uint32_t saddr; |
427 | 421 | |
428 | - saddr = (addr - PHYS_JJ_LEDMA) >> 2; | |
422 | + saddr = (addr - s->addr) >> 2; | |
429 | 423 | if (saddr < LEDMA_REGS) |
430 | 424 | s->regs[saddr] = val; |
431 | 425 | } |
... | ... | @@ -442,29 +436,31 @@ static CPUWriteMemoryFunc *ledma_mem_write[3] = { |
442 | 436 | ledma_mem_writel, |
443 | 437 | }; |
444 | 438 | |
445 | -void lance_init(NetDriverState *nd, int irq) | |
439 | +void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr) | |
446 | 440 | { |
447 | 441 | LANCEState *s; |
448 | 442 | LEDMAState *led; |
443 | + int lance_io_memory, ledma_io_memory; | |
449 | 444 | |
450 | 445 | s = qemu_mallocz(sizeof(LANCEState)); |
451 | 446 | if (!s) |
452 | 447 | return; |
453 | 448 | |
449 | + s->paddr = leaddr; | |
450 | + s->nd = nd; | |
451 | + s->irq = irq; | |
452 | + | |
454 | 453 | 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); | |
454 | + cpu_register_physical_memory(leaddr, 8, lance_io_memory); | |
455 | + | |
457 | 456 | led = qemu_mallocz(sizeof(LEDMAState)); |
458 | 457 | if (!led) |
459 | 458 | return; |
460 | 459 | |
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 | 460 | s->ledma = led; |
467 | - s->irq = irq; | |
461 | + led->addr = ledaddr; | |
462 | + ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led); | |
463 | + cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); | |
468 | 464 | |
469 | 465 | lance_reset(s); |
470 | 466 | qemu_add_read_packet(nd, lance_can_receive, lance_receive, s); | ... | ... |
hw/m48t08.c
... | ... | @@ -341,7 +341,7 @@ static CPUReadMemoryFunc *nvram_read[] = { |
341 | 341 | }; |
342 | 342 | |
343 | 343 | /* Initialisation routine */ |
344 | -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size) | |
344 | +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr) | |
345 | 345 | { |
346 | 346 | m48t08_t *s; |
347 | 347 | int i; |
... | ... | @@ -367,7 +367,7 @@ m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size) |
367 | 367 | i = 0x1fd8; |
368 | 368 | s->buffer[i++] = 0x01; |
369 | 369 | s->buffer[i++] = 0x80; /* Sun4m OBP */ |
370 | - /* XXX: Ethernet address, etc */ | |
370 | + memcpy(&s->buffer[i], macaddr, 6); | |
371 | 371 | |
372 | 372 | /* Calculate checksum */ |
373 | 373 | for (i = 0x1fd8; i < 0x1fe7; i++) { | ... | ... |
hw/m48t08.h
... | ... | @@ -7,6 +7,6 @@ void m48t08_write (m48t08_t *NVRAM, uint32_t val); |
7 | 7 | uint32_t m48t08_read (m48t08_t *NVRAM); |
8 | 8 | void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr); |
9 | 9 | void m48t08_toggle_lock (m48t08_t *NVRAM, int lock); |
10 | -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size); | |
10 | +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr); | |
11 | 11 | |
12 | 12 | #endif /* !defined (__M48T08_H__) */ | ... | ... |
hw/magic-load.c
1 | -/* This is the Linux kernel elf-loading code, ported into user space */ | |
2 | 1 | #include "vl.h" |
3 | 2 | #include "disas.h" |
4 | 3 | |
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 | 4 | #define ELF_CLASS ELFCLASS32 |
21 | 5 | #define ELF_DATA ELFDATA2MSB |
22 | 6 | #define ELF_ARCH EM_SPARC |
23 | 7 | |
24 | 8 | #include "elf.h" |
25 | 9 | |
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 | 10 | #ifdef BSWAP_NEEDED |
40 | 11 | static void bswap_ehdr(Elf32_Ehdr *ehdr) |
41 | 12 | { |
... | ... | @@ -87,186 +58,192 @@ static void bswap_sym(Elf32_Sym *sym) |
87 | 58 | bswap32s(&sym->st_size); |
88 | 59 | bswap16s(&sym->st_shndx); |
89 | 60 | } |
61 | +#else | |
62 | +#define bswap_ehdr(e) do { } while (0) | |
63 | +#define bswap_phdr(e) do { } while (0) | |
64 | +#define bswap_shdr(e) do { } while (0) | |
65 | +#define bswap_sym(e) do { } while (0) | |
90 | 66 | #endif |
91 | 67 | |
92 | -static int prepare_binprm(struct linux_binprm *bprm) | |
68 | +static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type) | |
93 | 69 | { |
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); | |
70 | + int i, retval; | |
71 | + | |
72 | + retval = lseek(fd, ehdr->e_phoff, SEEK_SET); | |
73 | + if (retval < 0) | |
74 | + return -1; | |
75 | + | |
76 | + for (i = 0; i < ehdr->e_phnum; i++) { | |
77 | + retval = read(fd, phdr, sizeof(*phdr)); | |
78 | + if (retval < 0) | |
79 | + return -1; | |
80 | + bswap_phdr(phdr); | |
81 | + if (phdr->p_type == type) | |
82 | + return 0; | |
108 | 83 | } |
84 | + return -1; | |
109 | 85 | } |
110 | 86 | |
111 | -/* Best attempt to load symbols from this ELF object. */ | |
112 | -static void load_symbols(struct elfhdr *hdr, int fd) | |
87 | +static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type) | |
113 | 88 | { |
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 | - } | |
89 | + int i, retval; | |
90 | + | |
91 | + retval = lseek(fd, ehdr->e_shoff, SEEK_SET); | |
92 | + if (retval < 0) | |
93 | + return NULL; | |
94 | + | |
95 | + for (i = 0; i < ehdr->e_shnum; i++) { | |
96 | + retval = read(fd, shdr, sizeof(*shdr)); | |
97 | + if (retval < 0) | |
98 | + return NULL; | |
99 | + bswap_shdr(shdr); | |
100 | + if (shdr->sh_type == type) | |
101 | + return qemu_malloc(shdr->sh_size); | |
137 | 102 | } |
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; | |
103 | + return NULL; | |
104 | +} | |
150 | 105 | |
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 | |
106 | +static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab) | |
107 | +{ | |
108 | + int retval; | |
155 | 109 | |
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); | |
110 | + retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET); | |
111 | + if (retval < 0) | |
112 | + return -1; | |
113 | + | |
114 | + retval = read(fd, shdr, sizeof(*shdr)); | |
115 | + if (retval < 0) | |
116 | + return -1; | |
117 | + bswap_shdr(shdr); | |
118 | + if (shdr->sh_type == SHT_STRTAB) | |
119 | + return qemu_malloc(shdr->sh_size);; | |
120 | + return 0; | |
160 | 121 | } |
161 | 122 | |
162 | -static int load_elf_binary(struct linux_binprm * bprm, uint8_t *addr) | |
123 | +static int read_program(int fd, struct elf_phdr *phdr, void *dst) | |
163 | 124 | { |
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 | 125 | int retval; |
126 | + retval = lseek(fd, 0x4000, SEEK_SET); | |
127 | + if (retval < 0) | |
128 | + return -1; | |
129 | + return read(fd, dst, phdr->p_filesz); | |
130 | +} | |
170 | 131 | |
171 | - elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ | |
172 | -#ifdef BSWAP_NEEDED | |
173 | - bswap_ehdr(&elf_ex); | |
174 | -#endif | |
132 | +static int read_section(int fd, struct elf_shdr *s, void *dst) | |
133 | +{ | |
134 | + int retval; | |
175 | 135 | |
176 | - if (elf_ex.e_ident[0] != 0x7f || | |
177 | - strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { | |
178 | - return -ENOEXEC; | |
179 | - } | |
136 | + retval = lseek(fd, s->sh_offset, SEEK_SET); | |
137 | + if (retval < 0) | |
138 | + return -1; | |
139 | + retval = read(fd, dst, s->sh_size); | |
140 | + if (retval < 0) | |
141 | + return -1; | |
142 | + return 0; | |
143 | +} | |
180 | 144 | |
181 | - /* First of all, some simple consistency checks */ | |
182 | - if (! elf_check_arch(elf_ex.e_machine)) { | |
183 | - return -ENOEXEC; | |
184 | - } | |
145 | +static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type) | |
146 | +{ | |
147 | + void *dst; | |
148 | + | |
149 | + dst = find_shdr(ehdr, fd, shdr, type); | |
150 | + if (!dst) | |
151 | + goto error; | |
152 | + | |
153 | + if (read_section(fd, shdr, dst)) | |
154 | + goto error; | |
155 | + return dst; | |
156 | + error: | |
157 | + qemu_free(dst); | |
158 | + return NULL; | |
159 | +} | |
185 | 160 | |
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 | - } | |
161 | +static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab) | |
162 | +{ | |
163 | + void *dst; | |
164 | + | |
165 | + dst = find_strtab(ehdr, fd, shdr, symtab); | |
166 | + if (!dst) | |
167 | + goto error; | |
168 | + | |
169 | + if (read_section(fd, shdr, dst)) | |
170 | + goto error; | |
171 | + return dst; | |
172 | + error: | |
173 | + qemu_free(dst); | |
174 | + return NULL; | |
175 | +} | |
191 | 176 | |
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 | - } | |
177 | +static void load_symbols(struct elfhdr *ehdr, int fd) | |
178 | +{ | |
179 | + struct elf_shdr symtab, strtab; | |
180 | + struct elf_sym *syms; | |
181 | + int nsyms, i; | |
182 | + char *str; | |
183 | + | |
184 | + /* Symbol table */ | |
185 | + syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB); | |
186 | + if (!syms) | |
187 | + return; | |
197 | 188 | |
198 | - if (retval < 0) { | |
199 | - perror("load_elf_binary"); | |
200 | - exit(-1); | |
201 | - qemu_free (elf_phdata); | |
202 | - return -errno; | |
203 | - } | |
189 | + nsyms = symtab.sh_size / sizeof(struct elf_sym); | |
190 | + for (i = 0; i < nsyms; i++) | |
191 | + bswap_sym(&syms[i]); | |
192 | + | |
193 | + /* String table */ | |
194 | + str = process_strtab(ehdr, fd, &strtab, &symtab); | |
195 | + if (!str) | |
196 | + goto error_freesyms; | |
197 | + | |
198 | + /* Commit */ | |
199 | + if (disas_symtab) | |
200 | + qemu_free(disas_symtab); /* XXX Merge with old symbols? */ | |
201 | + if (disas_strtab) | |
202 | + qemu_free(disas_strtab); | |
203 | + disas_symtab = syms; | |
204 | + disas_num_syms = nsyms; | |
205 | + disas_strtab = str; | |
206 | + return; | |
207 | + error_freesyms: | |
208 | + qemu_free(syms); | |
209 | + return; | |
210 | +} | |
204 | 211 | |
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 | - } | |
212 | +int load_elf(const char * filename, uint8_t *addr) | |
213 | +{ | |
214 | + struct elfhdr ehdr; | |
215 | + struct elf_phdr phdr; | |
216 | + int retval, fd; | |
244 | 217 | |
245 | - qemu_free(elf_phdata); | |
218 | + fd = open(filename, O_RDONLY | O_BINARY); | |
219 | + if (fd < 0) | |
220 | + goto error; | |
246 | 221 | |
247 | - load_symbols(&elf_ex, bprm->fd); | |
222 | + retval = read(fd, &ehdr, sizeof(ehdr)); | |
223 | + if (retval < 0) | |
224 | + goto error; | |
248 | 225 | |
249 | - return addr-startaddr; | |
250 | -} | |
226 | + bswap_ehdr(&ehdr); | |
251 | 227 | |
252 | -int elf_exec(const char * filename, uint8_t *addr) | |
253 | -{ | |
254 | - struct linux_binprm bprm; | |
255 | - int retval; | |
228 | + if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' | |
229 | + || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F' | |
230 | + || ehdr.e_machine != EM_SPARC) | |
231 | + goto error; | |
256 | 232 | |
257 | - retval = open(filename, O_RDONLY); | |
258 | - if (retval < 0) | |
259 | - return retval; | |
260 | - bprm.fd = retval; | |
233 | + if (find_phdr(&ehdr, fd, &phdr, PT_LOAD)) | |
234 | + goto error; | |
235 | + retval = read_program(fd, &phdr, addr); | |
236 | + if (retval < 0) | |
237 | + goto error; | |
261 | 238 | |
262 | - retval = prepare_binprm(&bprm); | |
239 | + load_symbols(&ehdr, fd); | |
263 | 240 | |
264 | - if(retval>=0) { | |
265 | - retval = load_elf_binary(&bprm, addr); | |
266 | - } | |
267 | - return retval; | |
241 | + close(fd); | |
242 | + return retval; | |
243 | + error: | |
244 | + close(fd); | |
245 | + return -1; | |
268 | 246 | } |
269 | -#endif | |
270 | 247 | |
271 | 248 | int load_kernel(const char *filename, uint8_t *addr) |
272 | 249 | { |
... | ... | @@ -286,28 +263,31 @@ int load_kernel(const char *filename, uint8_t *addr) |
286 | 263 | return -1; |
287 | 264 | } |
288 | 265 | |
289 | -static char saved_kfn[1024]; | |
290 | -static uint32_t saved_addr; | |
291 | -static int magic_state; | |
266 | +typedef struct MAGICState { | |
267 | + uint32_t addr; | |
268 | + uint32_t saved_addr; | |
269 | + int magic_state; | |
270 | + char saved_kfn[1024]; | |
271 | +} MAGICState; | |
292 | 272 | |
293 | 273 | static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr) |
294 | 274 | { |
295 | 275 | int ret; |
276 | + MAGICState *s = opaque; | |
296 | 277 | |
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 | |
278 | + if (s->magic_state == 0) { | |
279 | + ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr); | |
280 | + if (ret < 0) | |
281 | + ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr); | |
303 | 282 | if (ret < 0) { |
304 | 283 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
305 | - saved_kfn); | |
284 | + s->saved_kfn); | |
306 | 285 | } |
307 | - magic_state = 1; /* No more magic */ | |
286 | + s->magic_state = 1; /* No more magic */ | |
308 | 287 | tb_flush(); |
288 | + return bswap32(ret); | |
309 | 289 | } |
310 | - return ret; | |
290 | + return 0; | |
311 | 291 | } |
312 | 292 | |
313 | 293 | static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
... | ... | @@ -327,15 +307,20 @@ static CPUWriteMemoryFunc *magic_mem_write[3] = { |
327 | 307 | magic_mem_writel, |
328 | 308 | }; |
329 | 309 | |
330 | -void magic_init(const char *kfn, int kloadaddr) | |
310 | +void magic_init(const char *kfn, int kloadaddr, uint32_t addr) | |
331 | 311 | { |
332 | 312 | 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); | |
313 | + MAGICState *s; | |
314 | + | |
315 | + s = qemu_mallocz(sizeof(MAGICState)); | |
316 | + if (!s) | |
317 | + return; | |
318 | + | |
319 | + strcpy(s->saved_kfn, kfn); | |
320 | + s->saved_addr = kloadaddr; | |
321 | + s->magic_state = 0; | |
322 | + s->addr = addr; | |
323 | + magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s); | |
324 | + cpu_register_physical_memory(addr, 4, magic_io_memory); | |
340 | 325 | } |
341 | 326 | ... | ... |
hw/sched.c
1 | 1 | /* |
2 | - * QEMU interrupt controller & timer emulation | |
2 | + * QEMU interrupt controller emulation | |
3 | 3 | * |
4 | 4 | * Copyright (c) 2003-2004 Fabrice Bellard |
5 | 5 | * |
... | ... | @@ -22,11 +22,7 @@ |
22 | 22 | * THE SOFTWARE. |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | - | |
26 | -#define PHYS_JJ_CLOCK 0x71D00000 | |
27 | -#define PHYS_JJ_CLOCK1 0x71D10000 | |
28 | -#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ | |
29 | -#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ | |
25 | +//#define DEBUG_IRQ_COUNT | |
30 | 26 | |
31 | 27 | /* These registers are used for sending/receiving irqs from/to |
32 | 28 | * different cpu's. |
... | ... | @@ -63,18 +59,6 @@ struct sun4m_intreg_master { |
63 | 59 | /* This register is both READ and WRITE. */ |
64 | 60 | unsigned int undirected_target; /* Which cpu gets undirected irqs. */ |
65 | 61 | }; |
66 | -/* | |
67 | - * Registers of hardware timer in sun4m. | |
68 | - */ | |
69 | -struct sun4m_timer_percpu { | |
70 | - volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */ | |
71 | - volatile unsigned int l14_cur_count; | |
72 | -}; | |
73 | - | |
74 | -struct sun4m_timer_global { | |
75 | - volatile unsigned int l10_timer_limit; | |
76 | - volatile unsigned int l10_cur_count; | |
77 | -}; | |
78 | 62 | |
79 | 63 | #define SUN4M_INT_ENABLE 0x80000000 |
80 | 64 | #define SUN4M_INT_E14 0x00000080 |
... | ... | @@ -101,29 +85,25 @@ struct sun4m_timer_global { |
101 | 85 | #define SUN4M_INT_VME(x) (1 << (x)) |
102 | 86 | |
103 | 87 | typedef struct SCHEDState { |
88 | + uint32_t addr, addrg; | |
104 | 89 | uint32_t intreg_pending; |
105 | 90 | uint32_t intreg_enabled; |
106 | 91 | uint32_t intregm_pending; |
107 | 92 | uint32_t intregm_enabled; |
108 | - uint32_t timer_regs[2]; | |
109 | - uint32_t timerm_regs[2]; | |
110 | 93 | } SCHEDState; |
111 | 94 | |
112 | 95 | static SCHEDState *ps; |
113 | 96 | |
114 | -static int intreg_io_memory, intregm_io_memory, | |
115 | - timer_io_memory, timerm_io_memory; | |
116 | - | |
117 | -static void sched_reset(SCHEDState *s) | |
118 | -{ | |
119 | -} | |
97 | +#ifdef DEBUG_IRQ_COUNT | |
98 | +static uint64_t irq_count[32]; | |
99 | +#endif | |
120 | 100 | |
121 | 101 | static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr) |
122 | 102 | { |
123 | 103 | SCHEDState *s = opaque; |
124 | 104 | uint32_t saddr; |
125 | 105 | |
126 | - saddr = (addr - PHYS_JJ_INTR0) >> 2; | |
106 | + saddr = (addr - s->addr) >> 2; | |
127 | 107 | switch (saddr) { |
128 | 108 | case 0: |
129 | 109 | return s->intreg_pending; |
... | ... | @@ -139,7 +119,7 @@ static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va |
139 | 119 | SCHEDState *s = opaque; |
140 | 120 | uint32_t saddr; |
141 | 121 | |
142 | - saddr = (addr - PHYS_JJ_INTR0) >> 2; | |
122 | + saddr = (addr - s->addr) >> 2; | |
143 | 123 | switch (saddr) { |
144 | 124 | case 0: |
145 | 125 | s->intreg_pending = val; |
... | ... | @@ -172,7 +152,7 @@ static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr) |
172 | 152 | SCHEDState *s = opaque; |
173 | 153 | uint32_t saddr; |
174 | 154 | |
175 | - saddr = (addr - PHYS_JJ_INTR_G) >> 2; | |
155 | + saddr = (addr - s->addrg) >> 2; | |
176 | 156 | switch (saddr) { |
177 | 157 | case 0: |
178 | 158 | return s->intregm_pending; |
... | ... | @@ -191,7 +171,7 @@ static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t v |
191 | 171 | SCHEDState *s = opaque; |
192 | 172 | uint32_t saddr; |
193 | 173 | |
194 | - saddr = (addr - PHYS_JJ_INTR_G) >> 2; | |
174 | + saddr = (addr - s->addrg) >> 2; | |
195 | 175 | switch (saddr) { |
196 | 176 | case 0: |
197 | 177 | s->intregm_pending = val; |
... | ... | @@ -222,87 +202,29 @@ static CPUWriteMemoryFunc *intregm_mem_write[3] = { |
222 | 202 | intregm_mem_writel, |
223 | 203 | }; |
224 | 204 | |
225 | -static uint32_t timer_mem_readl(void *opaque, target_phys_addr_t addr) | |
205 | +void pic_info(void) | |
226 | 206 | { |
227 | - SCHEDState *s = opaque; | |
228 | - uint32_t saddr; | |
229 | - | |
230 | - saddr = (addr - PHYS_JJ_CLOCK) >> 2; | |
231 | - switch (saddr) { | |
232 | - default: | |
233 | - return s->timer_regs[saddr]; | |
234 | - break; | |
235 | - } | |
236 | - return 0; | |
207 | + term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled); | |
208 | + term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled); | |
237 | 209 | } |
238 | 210 | |
239 | -static void timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) | |
211 | +void irq_info(void) | |
240 | 212 | { |
241 | - SCHEDState *s = opaque; | |
242 | - uint32_t saddr; | |
243 | - | |
244 | - saddr = (addr - PHYS_JJ_CLOCK) >> 2; | |
245 | - switch (saddr) { | |
246 | - default: | |
247 | - s->timer_regs[saddr] = val; | |
248 | - break; | |
213 | +#ifndef DEBUG_IRQ_COUNT | |
214 | + term_printf("irq statistic code not compiled.\n"); | |
215 | +#else | |
216 | + int i; | |
217 | + int64_t count; | |
218 | + | |
219 | + term_printf("IRQ statistics:\n"); | |
220 | + for (i = 0; i < 32; i++) { | |
221 | + count = irq_count[i]; | |
222 | + if (count > 0) | |
223 | + term_printf("%2d: %lld\n", i, count); | |
249 | 224 | } |
225 | +#endif | |
250 | 226 | } |
251 | 227 | |
252 | -static CPUReadMemoryFunc *timer_mem_read[3] = { | |
253 | - timer_mem_readl, | |
254 | - timer_mem_readl, | |
255 | - timer_mem_readl, | |
256 | -}; | |
257 | - | |
258 | -static CPUWriteMemoryFunc *timer_mem_write[3] = { | |
259 | - timer_mem_writel, | |
260 | - timer_mem_writel, | |
261 | - timer_mem_writel, | |
262 | -}; | |
263 | - | |
264 | -static uint32_t timerm_mem_readl(void *opaque, target_phys_addr_t addr) | |
265 | -{ | |
266 | - SCHEDState *s = opaque; | |
267 | - uint32_t saddr; | |
268 | - | |
269 | - saddr = (addr - PHYS_JJ_CLOCK1) >> 2; | |
270 | - switch (saddr) { | |
271 | - default: | |
272 | - return s->timerm_regs[saddr]; | |
273 | - break; | |
274 | - } | |
275 | - return 0; | |
276 | -} | |
277 | - | |
278 | -static void timerm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) | |
279 | -{ | |
280 | - SCHEDState *s = opaque; | |
281 | - uint32_t saddr; | |
282 | - | |
283 | - saddr = (addr - PHYS_JJ_CLOCK1) >> 2; | |
284 | - switch (saddr) { | |
285 | - default: | |
286 | - s->timerm_regs[saddr] = val; | |
287 | - break; | |
288 | - } | |
289 | -} | |
290 | - | |
291 | -static CPUReadMemoryFunc *timerm_mem_read[3] = { | |
292 | - timerm_mem_readl, | |
293 | - timerm_mem_readl, | |
294 | - timerm_mem_readl, | |
295 | -}; | |
296 | - | |
297 | -static CPUWriteMemoryFunc *timerm_mem_write[3] = { | |
298 | - timerm_mem_writel, | |
299 | - timerm_mem_writel, | |
300 | - timerm_mem_writel, | |
301 | -}; | |
302 | - | |
303 | -void pic_info() {} | |
304 | -void irq_info() {} | |
305 | - | |
306 | 228 | static const unsigned int intr_to_mask[16] = { |
307 | 229 | 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0, |
308 | 230 | 0, 0, 0, 0, 0, 0, 0, 0, |
... | ... | @@ -318,29 +240,29 @@ void pic_set_irq(int irq, int level) |
318 | 240 | cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); |
319 | 241 | } |
320 | 242 | } |
243 | +#ifdef DEBUG_IRQ_COUNT | |
244 | + if (level == 1) | |
245 | + irq_count[irq]++; | |
246 | +#endif | |
321 | 247 | } |
322 | 248 | |
323 | -void sched_init() | |
249 | +void sched_init(uint32_t addr, uint32_t addrg) | |
324 | 250 | { |
251 | + int intreg_io_memory, intregm_io_memory; | |
325 | 252 | SCHEDState *s; |
326 | 253 | |
327 | 254 | s = qemu_mallocz(sizeof(SCHEDState)); |
328 | 255 | if (!s) |
329 | 256 | return; |
257 | + s->addr = addr; | |
258 | + s->addrg = addrg; | |
330 | 259 | |
331 | 260 | intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s); |
332 | - cpu_register_physical_memory(PHYS_JJ_INTR0, 3, intreg_io_memory); | |
261 | + cpu_register_physical_memory(addr, 3, intreg_io_memory); | |
333 | 262 | |
334 | 263 | intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s); |
335 | - cpu_register_physical_memory(PHYS_JJ_INTR_G, 5, intregm_io_memory); | |
336 | - | |
337 | - timer_io_memory = cpu_register_io_memory(0, timer_mem_read, timer_mem_write, s); | |
338 | - cpu_register_physical_memory(PHYS_JJ_CLOCK, 2, timer_io_memory); | |
339 | - | |
340 | - timerm_io_memory = cpu_register_io_memory(0, timerm_mem_read, timerm_mem_write, s); | |
341 | - cpu_register_physical_memory(PHYS_JJ_CLOCK1, 2, timerm_io_memory); | |
264 | + cpu_register_physical_memory(addrg, 5, intregm_io_memory); | |
342 | 265 | |
343 | - sched_reset(s); | |
344 | 266 | ps = s; |
345 | 267 | } |
346 | 268 | ... | ... |
hw/sun4m.c
... | ... | @@ -28,12 +28,26 @@ |
28 | 28 | #define MMU_CONTEXT_TBL 0x00003000 |
29 | 29 | #define MMU_L1PTP (MMU_CONTEXT_TBL + 0x0400) |
30 | 30 | #define MMU_L2PTP (MMU_CONTEXT_TBL + 0x0800) |
31 | -#define ROMVEC_DATA (MMU_CONTEXT_TBL + 0x1800) | |
32 | 31 | #define PROM_ADDR 0xffd04000 |
33 | -#define PROM_FILENAME "proll.bin" | |
32 | +#define PROM_FILENAMEB "proll.bin" | |
33 | +#define PROM_FILENAMEE "proll.elf" | |
34 | +#define PROLL_MAGIC_ADDR 0x20000000 | |
34 | 35 | #define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */ |
35 | 36 | #define PHYS_JJ_IDPROM_OFF 0x1FD8 |
36 | 37 | #define PHYS_JJ_EEPROM_SIZE 0x2000 |
38 | +#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ | |
39 | +#define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */ | |
40 | +#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */ | |
41 | +#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ | |
42 | +#define PHYS_JJ_LEDMA 0x78400010 /* ledma, off by 10 from unused SCSI */ | |
43 | +#define PHYS_JJ_LE 0x78C00000 /* LANCE, typical sun4m */ | |
44 | +#define PHYS_JJ_LE_IRQ 6 | |
45 | +#define PHYS_JJ_CLOCK 0x71D00000 | |
46 | +#define PHYS_JJ_CLOCK_IRQ 10 | |
47 | +#define PHYS_JJ_CLOCK1 0x71D10000 | |
48 | +#define PHYS_JJ_CLOCK1_IRQ 14 | |
49 | +#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ | |
50 | +#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ | |
37 | 51 | |
38 | 52 | /* TSC handling */ |
39 | 53 | |
... | ... | @@ -44,8 +58,6 @@ uint64_t cpu_get_tsc() |
44 | 58 | |
45 | 59 | void DMA_run() {} |
46 | 60 | void SB16_run() {} |
47 | -void vga_invalidate_display() {} | |
48 | -void vga_screen_dump(const char *filename) {} | |
49 | 61 | int serial_can_receive(SerialState *s) { return 0; } |
50 | 62 | void serial_receive_byte(SerialState *s, int ch) {} |
51 | 63 | void serial_receive_break(SerialState *s) {} |
... | ... | @@ -59,7 +71,7 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
59 | 71 | const char *initrd_filename) |
60 | 72 | { |
61 | 73 | char buf[1024]; |
62 | - int ret, linux_boot, bios_size; | |
74 | + int ret, linux_boot; | |
63 | 75 | unsigned long bios_offset; |
64 | 76 | |
65 | 77 | linux_boot = (kernel_filename != NULL); |
... | ... | @@ -68,32 +80,21 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
68 | 80 | cpu_register_physical_memory(0, ram_size, 0); |
69 | 81 | bios_offset = ram_size; |
70 | 82 | |
71 | - iommu_init(); | |
72 | - sched_init(); | |
73 | - tcx_init(ds); | |
74 | - lance_init(&nd_table[0], 6); | |
75 | - nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE); | |
76 | - | |
77 | - magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); | |
78 | - | |
79 | -#if 0 | |
80 | - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME); | |
81 | - bios_size = get_image_size(buf); | |
82 | - ret = load_image(buf, phys_ram_base + bios_offset); | |
83 | - if (ret != bios_size) { | |
84 | - fprintf(stderr, "qemu: could not load prom '%s'\n", buf); | |
85 | - exit(1); | |
86 | - } | |
87 | - cpu_register_physical_memory(PROM_ADDR, | |
88 | - bios_size, bios_offset | IO_MEM_ROM); | |
89 | -#endif | |
83 | + iommu_init(PHYS_JJ_IOMMU); | |
84 | + sched_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G); | |
85 | + tcx_init(ds, PHYS_JJ_TCX_FB); | |
86 | + lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA); | |
87 | + nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE, &nd_table[0].macaddr); | |
88 | + timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ); | |
89 | + timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ); | |
90 | + magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR, PROLL_MAGIC_ADDR); | |
90 | 91 | |
91 | 92 | /* We load Proll as the kernel and start it. It will issue a magic |
92 | 93 | IO to load the real kernel */ |
93 | 94 | if (linux_boot) { |
94 | - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME); | |
95 | + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); | |
95 | 96 | ret = load_kernel(buf, |
96 | - phys_ram_base + KERNEL_LOAD_ADDR); | |
97 | + phys_ram_base + KERNEL_LOAD_ADDR); | |
97 | 98 | if (ret < 0) { |
98 | 99 | fprintf(stderr, "qemu: could not load kernel '%s'\n", |
99 | 100 | buf); |
... | ... | @@ -103,28 +104,10 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
103 | 104 | /* Setup a MMU entry for entire address space */ |
104 | 105 | stl_raw(phys_ram_base + MMU_CONTEXT_TBL, (MMU_L1PTP >> 4) | 1); |
105 | 106 | stl_raw(phys_ram_base + MMU_L1PTP, (MMU_L2PTP >> 4) | 1); |
106 | -#if 0 | |
107 | - stl_raw(phys_ram_base + MMU_L1PTP + (0x50 << 2), (MMU_L2PTP >> 4) | 1); // frame buffer at 50.. | |
108 | -#endif | |
107 | + stl_raw(phys_ram_base + MMU_L1PTP + (0x01 << 2), (MMU_L2PTP >> 4) | 1); // 01.. == 00.. | |
109 | 108 | stl_raw(phys_ram_base + MMU_L1PTP + (0xff << 2), (MMU_L2PTP >> 4) | 1); // ff.. == 00.. |
109 | + stl_raw(phys_ram_base + MMU_L1PTP + (0xf0 << 2), (MMU_L2PTP >> 4) | 1); // f0.. == 00.. | |
110 | 110 | /* 3 = U:RWX S:RWX */ |
111 | 111 | stl_raw(phys_ram_base + MMU_L2PTP, (3 << PTE_ACCESS_SHIFT) | 2); |
112 | -#if 0 | |
113 | - stl_raw(phys_ram_base + MMU_L2PTP + 0x84, (PHYS_JJ_TCX_FB >> 4) \ | |
114 | - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf | |
115 | - stl_raw(phys_ram_base + MMU_L2PTP + 0x88, (PHYS_JJ_TCX_FB >> 4) \ | |
116 | - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf | |
117 | - stl_raw(phys_ram_base + MMU_L2PTP + 0x140, (PHYS_JJ_TCX_FB >> 4) \ | |
118 | - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf | |
119 | - // "Empirical constant" | |
120 | - stl_raw(phys_ram_base + ROMVEC_DATA, 0x10010407); | |
121 | - | |
122 | - // Version: V3 prom | |
123 | - stl_raw(phys_ram_base + ROMVEC_DATA + 4, 3); | |
124 | - | |
125 | - stl_raw(phys_ram_base + ROMVEC_DATA + 0x1c, ROMVEC_DATA+0x400); | |
126 | - stl_raw(phys_ram_base + ROMVEC_DATA + 0x400, ROMVEC_DATA+0x404); | |
127 | - stl_raw(phys_ram_base + ROMVEC_DATA + 0x404, 0x81c3e008); // retl | |
128 | - stl_raw(phys_ram_base + ROMVEC_DATA + 0x408, 0x01000000); // nop | |
129 | -#endif | |
112 | + stl_raw(phys_ram_base + MMU_L2PTP, ((0x01 << PTE_PPN_SHIFT) >> 4 ) | (3 << PTE_ACCESS_SHIFT) | 2); | |
130 | 113 | } | ... | ... |
hw/tcx.c
... | ... | @@ -23,9 +23,6 @@ |
23 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | 25 | |
26 | -#define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */ | |
27 | -#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */ | |
28 | - | |
29 | 26 | #define MAXX 1024 |
30 | 27 | #define MAXY 768 |
31 | 28 | #define XSZ (8*80) |
... | ... | @@ -33,38 +30,32 @@ |
33 | 30 | #define XOFF (MAXX-XSZ) |
34 | 31 | #define YOFF (MAXY-YSZ) |
35 | 32 | |
36 | -#define DEBUG_VGA_MEM | |
37 | - | |
38 | 33 | typedef struct TCXState { |
39 | - uint8_t *vram_ptr; | |
40 | - unsigned long vram_offset; | |
41 | - unsigned int vram_size; | |
34 | + uint32_t addr; | |
42 | 35 | DisplayState *ds; |
36 | + uint8_t *vram; | |
43 | 37 | } TCXState; |
44 | 38 | |
45 | 39 | static TCXState *ts; |
46 | 40 | |
47 | -static int tcx_io_memory; | |
48 | - | |
49 | 41 | void vga_update_display() |
50 | 42 | { |
51 | 43 | dpy_update(ts->ds, 0, 0, XSZ, YSZ); |
52 | 44 | } |
53 | 45 | |
46 | +void vga_invalidate_display() {} | |
47 | + | |
54 | 48 | static uint32_t tcx_mem_readb(void *opaque, target_phys_addr_t addr) |
55 | 49 | { |
56 | 50 | TCXState *s = opaque; |
57 | 51 | uint32_t saddr; |
58 | 52 | unsigned int x, y; |
59 | - char *sptr; | |
60 | 53 | |
61 | - saddr = addr - PHYS_JJ_TCX_FB - YOFF*MAXX - XOFF; | |
54 | + saddr = addr - s->addr - YOFF*MAXX - XOFF; | |
62 | 55 | y = saddr / MAXX; |
63 | 56 | x = saddr - y * MAXX; |
64 | - if (x < MAXX && y < MAXY) { | |
65 | - sptr = s->ds->data; | |
66 | - if (sptr) | |
67 | - return sptr[y * s->ds->linesize + x*4]; | |
57 | + if (x < XSZ && y < YSZ) { | |
58 | + return s->vram[y * XSZ + x]; | |
68 | 59 | } |
69 | 60 | return 0; |
70 | 61 | } |
... | ... | @@ -99,7 +90,6 @@ static uint32_t tcx_mem_readl(void *opaque, target_phys_addr_t addr) |
99 | 90 | return v; |
100 | 91 | } |
101 | 92 | |
102 | -/* called for accesses between 0xa0000 and 0xc0000 */ | |
103 | 93 | static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) |
104 | 94 | { |
105 | 95 | TCXState *s = opaque; |
... | ... | @@ -107,17 +97,24 @@ static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) |
107 | 97 | unsigned int x, y; |
108 | 98 | char *sptr; |
109 | 99 | |
110 | - saddr = addr - PHYS_JJ_TCX_FB - YOFF*MAXX - XOFF; | |
100 | + saddr = addr - s->addr - YOFF*MAXX - XOFF; | |
111 | 101 | y = saddr / MAXX; |
112 | 102 | x = saddr - y * MAXX; |
113 | - if (x < MAXX && y < MAXY) { | |
103 | + if (x < XSZ && y < YSZ) { | |
114 | 104 | sptr = s->ds->data; |
115 | 105 | if (sptr) { |
116 | - sptr[y * s->ds->linesize + x*4] = val; | |
117 | - sptr[y * s->ds->linesize + x*4+1] = val; | |
118 | - sptr[y * s->ds->linesize + x*4+2] = val; | |
119 | - cpu_physical_memory_set_dirty(addr); | |
106 | + if (s->ds->depth == 24 || s->ds->depth == 32) { | |
107 | + /* XXX need to do CLUT translation */ | |
108 | + sptr[y * s->ds->linesize + x*4] = val & 0xff; | |
109 | + sptr[y * s->ds->linesize + x*4+1] = val & 0xff; | |
110 | + sptr[y * s->ds->linesize + x*4+2] = val & 0xff; | |
111 | + } | |
112 | + else if (s->ds->depth == 8) { | |
113 | + sptr[y * s->ds->linesize + x] = val & 0xff; | |
114 | + } | |
120 | 115 | } |
116 | + cpu_physical_memory_set_dirty(addr); | |
117 | + s->vram[y * XSZ + x] = val & 0xff; | |
121 | 118 | } |
122 | 119 | } |
123 | 120 | |
... | ... | @@ -159,18 +156,52 @@ static CPUWriteMemoryFunc *tcx_mem_write[3] = { |
159 | 156 | tcx_mem_writel, |
160 | 157 | }; |
161 | 158 | |
162 | -void tcx_init(DisplayState *ds) | |
159 | +void tcx_init(DisplayState *ds, uint32_t addr) | |
163 | 160 | { |
164 | 161 | TCXState *s; |
162 | + int tcx_io_memory; | |
165 | 163 | |
166 | 164 | s = qemu_mallocz(sizeof(TCXState)); |
167 | 165 | if (!s) |
168 | 166 | return; |
169 | 167 | s->ds = ds; |
168 | + s->addr = addr; | |
170 | 169 | ts = s; |
171 | 170 | tcx_io_memory = cpu_register_io_memory(0, tcx_mem_read, tcx_mem_write, s); |
172 | - cpu_register_physical_memory(PHYS_JJ_TCX_FB, 0x100000, | |
171 | + cpu_register_physical_memory(addr, 0x100000, | |
173 | 172 | tcx_io_memory); |
173 | + s->vram = qemu_mallocz(XSZ*YSZ); | |
174 | 174 | dpy_resize(s->ds, XSZ, YSZ); |
175 | 175 | } |
176 | 176 | |
177 | +void vga_screen_dump(const char *filename) | |
178 | +{ | |
179 | + TCXState *s = ts; | |
180 | + FILE *f; | |
181 | + uint8_t *d, *d1; | |
182 | + unsigned int v; | |
183 | + int y, x; | |
184 | + | |
185 | + f = fopen(filename, "wb"); | |
186 | + if (!f) | |
187 | + return -1; | |
188 | + fprintf(f, "P6\n%d %d\n%d\n", | |
189 | + XSZ, YSZ, 255); | |
190 | + d1 = s->vram; | |
191 | + for(y = 0; y < YSZ; y++) { | |
192 | + d = d1; | |
193 | + for(x = 0; x < XSZ; x++) { | |
194 | + v = *d; | |
195 | + fputc((v) & 0xff, f); | |
196 | + fputc((v) & 0xff, f); | |
197 | + fputc((v) & 0xff, f); | |
198 | + d++; | |
199 | + } | |
200 | + d1 += XSZ; | |
201 | + } | |
202 | + fclose(f); | |
203 | + return; | |
204 | +} | |
205 | + | |
206 | + | |
207 | + | ... | ... |
monitor.c
... | ... | @@ -952,11 +952,7 @@ static int monitor_get_tbl (struct MonitorDef *md, int val) |
952 | 952 | #if defined(TARGET_SPARC) |
953 | 953 | static int monitor_get_psr (struct MonitorDef *md, int val) |
954 | 954 | { |
955 | - return (0<<28) | (4<<24) | cpu_single_env->psr \ | |
956 | - | (cpu_single_env->psrs? PSR_S : 0) \ | |
957 | - | (cpu_single_env->psrs? PSR_PS : 0) \ | |
958 | - | (cpu_single_env->psret? PSR_ET : 0) \ | |
959 | - | cpu_single_env->cwp; | |
955 | + return GET_PSR(cpu_single_env); | |
960 | 956 | } |
961 | 957 | |
962 | 958 | static int monitor_get_reg(struct MonitorDef *md, int val) | ... | ... |
pc-bios/README
... | ... | @@ -6,3 +6,8 @@ |
6 | 6 | |
7 | 7 | - The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is |
8 | 8 | available at http://site.voila.fr/jmayer/OpenHackWare/index.htm. |
9 | + | |
10 | +- Proll is a GPL'd boot PROM for Sparc JavaStations | |
11 | + (http://people.redhat.com/zaitcev/linux/). | |
12 | + Applying proll.patch allows circumventing some bugs and enables | |
13 | + faster kernel load through a hack. | ... | ... |
pc-bios/proll.bin
0 โ 100644
No preview for this file type
pc-bios/proll.patch
0 โ 100644
1 | +diff -ru proll_18.orig/mrcoffee/main.c proll_18/mrcoffee/main.c | |
2 | +--- proll_18.orig/mrcoffee/main.c 2002-09-13 16:16:59.000000000 +0200 | |
3 | ++++ proll_18/mrcoffee/main.c 2004-09-26 11:52:23.000000000 +0200 | |
4 | +@@ -101,6 +101,7 @@ | |
5 | + le_probe(); | |
6 | + init_net(); | |
7 | + | |
8 | ++#ifdef ORIG | |
9 | + #if 0 /* RARP */ | |
10 | + if (rarp() != 0) fatal(); | |
11 | + /* printrarp(); */ | |
12 | +@@ -117,13 +118,20 @@ | |
13 | + xtoa(myipaddr, fname, 8); | |
14 | + if (load(boot_rec.bp_siaddr, fname) != 0) fatal(); | |
15 | + #endif | |
16 | ++#endif | |
17 | + | |
18 | + romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas); | |
19 | + | |
20 | + printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n", | |
21 | + PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024, | |
22 | + (int)cio.start, (int)cio.curp); | |
23 | ++#ifdef ORIG | |
24 | + set_timeout(5); while (!chk_timeout()) { } /* P3: let me read */ | |
25 | ++#else | |
26 | ++ printk("loading kernel:"); | |
27 | ++ i = ld_bypass(0x20000000); | |
28 | ++ printk(" done, size %d\n", i); | |
29 | ++#endif | |
30 | + | |
31 | + { | |
32 | + void (*entry)(void *, int) = (void (*)(void*, int)) LOADBASE; | |
33 | +diff -ru proll_18.orig/mrcoffee/openprom.c proll_18/mrcoffee/openprom.c | |
34 | +--- proll_18.orig/mrcoffee/openprom.c 2002-09-13 16:17:03.000000000 +0200 | |
35 | ++++ proll_18/mrcoffee/openprom.c 2004-09-21 21:27:16.000000000 +0200 | |
36 | +@@ -144,10 +144,14 @@ | |
37 | + }; | |
38 | + | |
39 | + static int cpu_nctx = NCTX_SWIFT; | |
40 | ++static int cpu_cache_line_size = 0x20; | |
41 | ++static int cpu_cache_nlines = 0x200; | |
42 | + static struct property propv_cpu[] = { | |
43 | + {"name", "STP1012PGA", sizeof("STP1012PGA") }, | |
44 | + {"device_type", "cpu", 4 }, | |
45 | + {"mmu-nctx", (char*)&cpu_nctx, sizeof(int)}, | |
46 | ++ {"cache-line-size", (char*)&cpu_cache_line_size, sizeof(int)}, | |
47 | ++ {"cache-nlines", (char*)&cpu_cache_nlines, sizeof(int)}, | |
48 | + {NULL, NULL, -1} | |
49 | + }; | |
50 | + | ... | ... |
target-sparc/cpu.h
target-sparc/exec.h
... | ... | @@ -23,13 +23,16 @@ void helper_flush(target_ulong addr); |
23 | 23 | void helper_ld_asi(int asi, int size, int sign); |
24 | 24 | void helper_st_asi(int asi, int size, int sign); |
25 | 25 | void helper_rett(void); |
26 | -void helper_stfsr(void); | |
26 | +void helper_ldfsr(void); | |
27 | 27 | void set_cwp(int new_cwp); |
28 | 28 | void do_fabss(void); |
29 | 29 | void do_fsqrts(void); |
30 | 30 | void do_fsqrtd(void); |
31 | 31 | void do_fcmps(void); |
32 | 32 | void do_fcmpd(void); |
33 | +void do_ldd_kernel(uint32_t addr); | |
34 | +void do_ldd_user(uint32_t addr); | |
35 | +void do_ldd_raw(uint32_t addr); | |
33 | 36 | void do_interrupt(int intno, int is_int, int error_code, |
34 | 37 | unsigned int next_eip, int is_hw); |
35 | 38 | void raise_exception_err(int exception_index, int error_code); | ... | ... |
target-sparc/helper.c
... | ... | @@ -21,19 +21,10 @@ |
21 | 21 | |
22 | 22 | #define DEBUG_PCALL |
23 | 23 | |
24 | -#if 0 | |
25 | -#define raise_exception_err(a, b)\ | |
26 | -do {\ | |
27 | - fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ | |
28 | - (raise_exception_err)(a, b);\ | |
29 | -} while (0) | |
30 | -#endif | |
31 | - | |
32 | 24 | /* Sparc MMU emulation */ |
33 | 25 | int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
34 | 26 | int is_user, int is_softmmu); |
35 | 27 | |
36 | - | |
37 | 28 | /* thread support */ |
38 | 29 | |
39 | 30 | spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; |
... | ... | @@ -48,15 +39,6 @@ void cpu_unlock(void) |
48 | 39 | spin_unlock(&global_cpu_lock); |
49 | 40 | } |
50 | 41 | |
51 | -#if 0 | |
52 | -void cpu_loop_exit(void) | |
53 | -{ | |
54 | - /* NOTE: the register at this point must be saved by hand because | |
55 | - longjmp restore them */ | |
56 | - longjmp(env->jmp_env, 1); | |
57 | -} | |
58 | -#endif | |
59 | - | |
60 | 42 | #if !defined(CONFIG_USER_ONLY) |
61 | 43 | |
62 | 44 | #define MMUSUFFIX _mmu |
... | ... | @@ -258,7 +240,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, |
258 | 240 | env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; |
259 | 241 | env->mmuregs[4] = address; /* Fault address register */ |
260 | 242 | |
261 | - if (env->mmuregs[0] & MMU_NF) // No fault | |
243 | + if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault | |
262 | 244 | return 0; |
263 | 245 | |
264 | 246 | env->exception_index = exception; |
... | ... | @@ -306,7 +288,7 @@ void do_interrupt(int intno, int is_int, int error_code, |
306 | 288 | fprintf(logfile, "%6d: v=%02x e=%04x i=%d pc=%08x npc=%08x SP=%08x\n", |
307 | 289 | count, intno, error_code, is_int, |
308 | 290 | env->pc, |
309 | - env->npc, env->gregs[7]); | |
291 | + env->npc, env->regwptr[6]); | |
310 | 292 | #if 0 |
311 | 293 | cpu_sparc_dump_state(env, logfile, 0); |
312 | 294 | { | ... | ... |
target-sparc/op.c
... | ... | @@ -474,92 +474,6 @@ void OPPROTO op_sra(void) |
474 | 474 | T0 = ((int32_t) T0) >> T1; |
475 | 475 | } |
476 | 476 | |
477 | -#if 0 | |
478 | -void OPPROTO op_st(void) | |
479 | -{ | |
480 | - stl((void *) T0, T1); | |
481 | -} | |
482 | - | |
483 | -void OPPROTO op_stb(void) | |
484 | -{ | |
485 | - stb((void *) T0, T1); | |
486 | -} | |
487 | - | |
488 | -void OPPROTO op_sth(void) | |
489 | -{ | |
490 | - stw((void *) T0, T1); | |
491 | -} | |
492 | - | |
493 | -void OPPROTO op_std(void) | |
494 | -{ | |
495 | - stl((void *) T0, T1); | |
496 | - stl((void *) (T0 + 4), T2); | |
497 | -} | |
498 | - | |
499 | -void OPPROTO op_ld(void) | |
500 | -{ | |
501 | - T1 = ldl((void *) T0); | |
502 | -} | |
503 | - | |
504 | -void OPPROTO op_ldub(void) | |
505 | -{ | |
506 | - T1 = ldub((void *) T0); | |
507 | -} | |
508 | - | |
509 | -void OPPROTO op_lduh(void) | |
510 | -{ | |
511 | - T1 = lduw((void *) T0); | |
512 | -} | |
513 | - | |
514 | -void OPPROTO op_ldsb(void) | |
515 | -{ | |
516 | - T1 = ldsb((void *) T0); | |
517 | -} | |
518 | - | |
519 | -void OPPROTO op_ldsh(void) | |
520 | -{ | |
521 | - T1 = ldsw((void *) T0); | |
522 | -} | |
523 | - | |
524 | -void OPPROTO op_ldstub(void) | |
525 | -{ | |
526 | - T1 = ldub((void *) T0); | |
527 | - stb((void *) T0, 0xff); /* XXX: Should be Atomically */ | |
528 | -} | |
529 | - | |
530 | -void OPPROTO op_swap(void) | |
531 | -{ | |
532 | - unsigned int tmp = ldl((void *) T0); | |
533 | - stl((void *) T0, T1); /* XXX: Should be Atomically */ | |
534 | - T1 = tmp; | |
535 | -} | |
536 | - | |
537 | -void OPPROTO op_ldd(void) | |
538 | -{ | |
539 | - T1 = ldl((void *) T0); | |
540 | - T0 = ldl((void *) (T0 + 4)); | |
541 | -} | |
542 | - | |
543 | -void OPPROTO op_stf(void) | |
544 | -{ | |
545 | - stfl((void *) T0, FT0); | |
546 | -} | |
547 | - | |
548 | -void OPPROTO op_stdf(void) | |
549 | -{ | |
550 | - stfq((void *) T0, DT0); | |
551 | -} | |
552 | - | |
553 | -void OPPROTO op_ldf(void) | |
554 | -{ | |
555 | - FT0 = ldfl((void *) T0); | |
556 | -} | |
557 | - | |
558 | -void OPPROTO op_lddf(void) | |
559 | -{ | |
560 | - DT0 = ldfq((void *) T0); | |
561 | -} | |
562 | -#else | |
563 | 477 | /* Load and store */ |
564 | 478 | #define MEMSUFFIX _raw |
565 | 479 | #include "op_mem.h" |
... | ... | @@ -570,19 +484,16 @@ void OPPROTO op_lddf(void) |
570 | 484 | #define MEMSUFFIX _kernel |
571 | 485 | #include "op_mem.h" |
572 | 486 | #endif |
573 | -#endif | |
574 | 487 | |
575 | 488 | void OPPROTO op_ldfsr(void) |
576 | 489 | { |
577 | 490 | env->fsr = *((uint32_t *) &FT0); |
578 | - FORCE_RET(); | |
491 | + helper_ldfsr(); | |
579 | 492 | } |
580 | 493 | |
581 | 494 | void OPPROTO op_stfsr(void) |
582 | 495 | { |
583 | 496 | *((uint32_t *) &FT0) = env->fsr; |
584 | - helper_stfsr(); | |
585 | - FORCE_RET(); | |
586 | 497 | } |
587 | 498 | |
588 | 499 | void OPPROTO op_wry(void) |
... | ... | @@ -609,16 +520,17 @@ void OPPROTO op_wrwim(void) |
609 | 520 | void OPPROTO op_rdpsr(void) |
610 | 521 | { |
611 | 522 | T0 = GET_PSR(env); |
612 | - FORCE_RET(); | |
613 | 523 | } |
614 | 524 | |
615 | 525 | void OPPROTO op_wrpsr(void) |
616 | 526 | { |
527 | + int cwp; | |
617 | 528 | env->psr = T0 & ~PSR_ICC; |
618 | 529 | env->psrs = (T0 & PSR_S)? 1 : 0; |
619 | 530 | env->psrps = (T0 & PSR_PS)? 1 : 0; |
620 | 531 | env->psret = (T0 & PSR_ET)? 1 : 0; |
621 | - env->cwp = (T0 & PSR_CWP); | |
532 | + cwp = (T0 & PSR_CWP) & (NWINDOWS - 1); | |
533 | + set_cwp(cwp); | |
622 | 534 | FORCE_RET(); |
623 | 535 | } |
624 | 536 | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -104,6 +104,27 @@ void OPPROTO helper_st_asi(int asi, int size, int sign) |
104 | 104 | } |
105 | 105 | } |
106 | 106 | |
107 | +#if 0 | |
108 | +void do_ldd_raw(uint32_t addr) | |
109 | +{ | |
110 | + T1 = ldl_raw((void *) addr); | |
111 | + T0 = ldl_raw((void *) (addr + 4)); | |
112 | +} | |
113 | + | |
114 | +#if !defined(CONFIG_USER_ONLY) | |
115 | +void do_ldd_user(uint32_t addr) | |
116 | +{ | |
117 | + T1 = ldl_user((void *) addr); | |
118 | + T0 = ldl_user((void *) (addr + 4)); | |
119 | +} | |
120 | +void do_ldd_kernel(uint32_t addr) | |
121 | +{ | |
122 | + T1 = ldl_kernel((void *) addr); | |
123 | + T0 = ldl_kernel((void *) (addr + 4)); | |
124 | +} | |
125 | +#endif | |
126 | +#endif | |
127 | + | |
107 | 128 | void OPPROTO helper_rett() |
108 | 129 | { |
109 | 130 | int cwp; |
... | ... | @@ -116,7 +137,7 @@ void OPPROTO helper_rett() |
116 | 137 | env->psrs = env->psrps; |
117 | 138 | } |
118 | 139 | |
119 | -void helper_stfsr(void) | |
140 | +void helper_ldfsr(void) | |
120 | 141 | { |
121 | 142 | switch (env->fsr & FSR_RD_MASK) { |
122 | 143 | case FSR_RD_NEAREST: | ... | ... |
target-sparc/op_mem.h
... | ... | @@ -43,8 +43,12 @@ void OPPROTO glue(op_swap, MEMSUFFIX)(void) |
43 | 43 | |
44 | 44 | void OPPROTO glue(op_ldd, MEMSUFFIX)(void) |
45 | 45 | { |
46 | +#if 1 | |
46 | 47 | T1 = glue(ldl, MEMSUFFIX)((void *) T0); |
47 | 48 | T0 = glue(ldl, MEMSUFFIX)((void *) (T0 + 4)); |
49 | +#else | |
50 | + glue(do_ldd, MEMSUFFIX)(T0); | |
51 | +#endif | |
48 | 52 | } |
49 | 53 | |
50 | 54 | /*** Floating-point store ***/ | ... | ... |
tests/Makefile
vl.h
... | ... | @@ -673,20 +673,23 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
673 | 673 | const char *initrd_filename); |
674 | 674 | |
675 | 675 | /* iommu.c */ |
676 | -void iommu_init(); | |
676 | +void iommu_init(uint32_t addr); | |
677 | 677 | uint32_t iommu_translate(uint32_t addr); |
678 | 678 | |
679 | 679 | /* lance.c */ |
680 | -void lance_init(NetDriverState *nd, int irq); | |
680 | +void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr); | |
681 | 681 | |
682 | 682 | /* tcx.c */ |
683 | -void tcx_init(DisplayState *ds); | |
683 | +void tcx_init(DisplayState *ds, uint32_t addr); | |
684 | 684 | |
685 | 685 | /* sched.c */ |
686 | 686 | void sched_init(); |
687 | 687 | |
688 | 688 | /* magic-load.c */ |
689 | -void magic_init(const char *kfn, int kloadaddr); | |
689 | +void magic_init(const char *kfn, int kloadaddr, uint32_t addr); | |
690 | + | |
691 | +/* timer.c */ | |
692 | +void timer_init(uint32_t addr, int irq); | |
690 | 693 | |
691 | 694 | /* NVRAM helpers */ |
692 | 695 | #include "hw/m48t59.h" | ... | ... |