From 8d5f07fa3bd3433e779d13eb1cda4fbb07acb67f Mon Sep 17 00:00:00 2001 From: bellard Date: Mon, 4 Oct 2004 21:23:09 +0000 Subject: [PATCH] sparc merge (Blue Swirl) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1098 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile | 11 +- Makefile.target | 2 +- gdbstub.c | 6 + hw/iommu.c | 83 ++++---- hw/lance.c | 42 ++-- hw/m48t08.c | 4 +- hw/m48t08.h | 2 +- hw/magic-load.c | 403 +++++++++++++++++++-------------------- hw/sched.c | 148 ++++---------- hw/sun4m.c | 77 +++----- hw/tcx.c | 81 +++++--- monitor.c | 6 +- pc-bios/README | 5 + pc-bios/proll.bin | Bin 0 -> 56856 bytes pc-bios/proll.patch | 50 +++++ target-sparc/cpu.h | 1 + target-sparc/exec.h | 5 +- target-sparc/helper.c | 22 +-- target-sparc/op.c | 96 +--------- target-sparc/op_helper.c | 23 ++- target-sparc/op_mem.h | 4 + tests/Makefile | 2 +- vl.h | 11 +- 23 files changed, 492 insertions(+), 592 deletions(-) create mode 100644 pc-bios/proll.bin create mode 100644 pc-bios/proll.patch diff --git a/Makefile b/Makefile index f80db8be9f..d4d8028f3d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -include config-host.mak +-include config-host.mak CFLAGS=-Wall -O2 -g -fno-strict-aliasing ifdef CONFIG_DARWIN @@ -14,8 +14,9 @@ TOOLS=qemu-img ifdef CONFIG_STATIC LDFLAGS+=-static endif +DOCS=qemu-doc.html qemu-tech.html qemu.1 -all: dyngen$(EXESUF) $(TOOLS) qemu-doc.html qemu-tech.html qemu.1 +all: dyngen$(EXESUF) $(TOOLS) $(DOCS) for d in $(TARGET_DIRS); do \ $(MAKE) -C $$d $@ || exit 1 ; \ done @@ -29,14 +30,14 @@ dyngen$(EXESUF): dyngen.c clean: # avoid old build problems by removing potentially incorrect old files 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 - rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod + rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~ $(MAKE) -C tests clean for d in $(TARGET_DIRS); do \ $(MAKE) -C $$d $@ || exit 1 ; \ done distclean: clean - rm -f config-host.mak config-host.h + rm -f config-host.mak config-host.h $(DOCS) for d in $(TARGET_DIRS); do \ rm -rf $$d || exit 1 ; \ done @@ -50,6 +51,7 @@ endif install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \ pc-bios/vgabios-cirrus.bin \ pc-bios/ppc_rom.bin \ + pc-bios/proll.bin \ pc-bios/linux_boot.bin "$(datadir)" mkdir -p "$(docdir)" install -m 644 qemu-doc.html qemu-tech.html "$(docdir)" @@ -99,6 +101,7 @@ tarbin: $(datadir)/vgabios.bin \ $(datadir)/vgabios-cirrus.bin \ $(datadir)/ppc_rom.bin \ + $(datadir)/proll.bin \ $(datadir)/linux_boot.bin \ $(docdir)/qemu-doc.html \ $(docdir)/qemu-tech.html \ diff --git a/Makefile.target b/Makefile.target index ff07be844f..6ac8d9f1b0 100644 --- a/Makefile.target +++ b/Makefile.target @@ -279,7 +279,7 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o endif ifeq ($(TARGET_ARCH), sparc) -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o timer.o endif ifdef CONFIG_GDBSTUB VL_OBJS+=gdbstub.o diff --git a/gdbstub.c b/gdbstub.c index e15216a590..2491c2cd77 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -387,6 +387,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) env->eip = addr; #elif defined (TARGET_PPC) env->nip = addr; +#elif defined (TARGET_SPARC) + env->pc = addr; + env->npc = addr + 4; #endif } vm_start(); @@ -398,6 +401,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) env->eip = addr; #elif defined (TARGET_PPC) env->nip = addr; +#elif defined (TARGET_SPARC) + env->pc = addr; + env->npc = addr + 4; #endif } cpu_single_step(env, 1); diff --git a/hw/iommu.c b/hw/iommu.c index f00bb78b03..a9249c4ba7 100644 --- a/hw/iommu.c +++ b/hw/iommu.c @@ -107,29 +107,24 @@ struct iommu_regs { #define IOPTE_VALID 0x00000002 /* IOPTE is valid */ #define IOPTE_WAZ 0x00000001 /* Write as zeros */ -#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ #define PAGE_SHIFT 12 #define PAGE_SIZE (1 << PAGE_SHIFT) #define PAGE_MASK (PAGE_SIZE - 1) typedef struct IOMMUState { + uint32_t addr; uint32_t regs[sizeof(struct iommu_regs)]; + uint32_t iostart; } IOMMUState; static IOMMUState *ps; -static int iommu_io_memory; - -static void iommu_reset(IOMMUState *s) -{ -} - static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) { IOMMUState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_IOMMU) >> 2; + saddr = (addr - s->addr) >> 2; switch (saddr) { default: return s->regs[saddr]; @@ -143,8 +138,37 @@ static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val IOMMUState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_IOMMU) >> 2; + saddr = (addr - s->addr) >> 2; switch (saddr) { + case 0: + switch (val & IOMMU_CTRL_RNGE) { + case IOMMU_RNGE_16MB: + s->iostart = 0xff000000; + break; + case IOMMU_RNGE_32MB: + s->iostart = 0xfe000000; + break; + case IOMMU_RNGE_64MB: + s->iostart = 0xfc000000; + break; + case IOMMU_RNGE_128MB: + s->iostart = 0xf8000000; + break; + case IOMMU_RNGE_256MB: + s->iostart = 0xf0000000; + break; + case IOMMU_RNGE_512MB: + s->iostart = 0xe0000000; + break; + case IOMMU_RNGE_1GB: + s->iostart = 0xc0000000; + break; + default: + case IOMMU_RNGE_2GB: + s->iostart = 0x80000000; + break; + } + /* Fall through */ default: s->regs[saddr] = val; break; @@ -165,57 +189,30 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = { uint32_t iommu_translate(uint32_t addr) { - uint32_t *iopte = (void *)(ps->regs[1] << 4), pa, iostart; + uint32_t *iopte = (void *)(ps->regs[1] << 4), pa; - switch (ps->regs[0] & IOMMU_CTRL_RNGE) { - case IOMMU_RNGE_16MB: - iostart = 0xff000000; - break; - case IOMMU_RNGE_32MB: - iostart = 0xfe000000; - break; - case IOMMU_RNGE_64MB: - iostart = 0xfc000000; - break; - case IOMMU_RNGE_128MB: - iostart = 0xf8000000; - break; - case IOMMU_RNGE_256MB: - iostart = 0xf0000000; - break; - case IOMMU_RNGE_512MB: - iostart = 0xe0000000; - break; - case IOMMU_RNGE_1GB: - iostart = 0xc0000000; - break; - default: - case IOMMU_RNGE_2GB: - iostart = 0x80000000; - break; - } - - iopte += ((addr - iostart) >> PAGE_SHIFT); + iopte += ((addr - ps->iostart) >> PAGE_SHIFT); cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0); bswap32s(&pa); pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */ - //return pa + PAGE_SIZE; return pa + (addr & PAGE_MASK); } -void iommu_init() +void iommu_init(uint32_t addr) { IOMMUState *s; + int iommu_io_memory; s = qemu_mallocz(sizeof(IOMMUState)); if (!s) return; + s->addr = addr; + iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_IOMMU, sizeof(struct iommu_regs), + cpu_register_physical_memory(addr, sizeof(struct iommu_regs), iommu_io_memory); - iommu_reset(s); ps = s; } diff --git a/hw/lance.c b/hw/lance.c index e461adead1..25ad8c45b2 100644 --- a/hw/lance.c +++ b/hw/lance.c @@ -24,11 +24,7 @@ #include "vl.h" /* debug LANCE card */ -#define DEBUG_LANCE - -#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ -#define PHYS_JJ_LEDMA 0x78400010 /* ledma, off by 10 from unused SCSI */ -#define PHYS_JJ_LE 0x78C00000 /* LANCE, typical sun4m */ +//#define DEBUG_LANCE #ifndef LANCE_LOG_TX_BUFFERS #define LANCE_LOG_TX_BUFFERS 4 @@ -162,10 +158,12 @@ struct sparc_dma_registers { #endif typedef struct LEDMAState { + uint32_t addr; uint32_t regs[LEDMA_REGS]; } LEDMAState; typedef struct LANCEState { + uint32_t paddr; NetDriverState *nd; uint32_t leptr; uint16_t addr; @@ -175,8 +173,6 @@ typedef struct LANCEState { LEDMAState *ledma; } LANCEState; -static int lance_io_memory; - static unsigned int rxptr, txptr; static void lance_send(void *opaque); @@ -194,7 +190,7 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) LANCEState *s = opaque; uint32_t saddr; - saddr = addr - PHYS_JJ_LE; + saddr = addr - s->paddr; switch (saddr >> 1) { case LE_RDP: return s->regs[s->addr]; @@ -210,9 +206,9 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val { LANCEState *s = opaque; uint32_t saddr; - uint16_t clear, reg; + uint16_t reg; - saddr = addr - PHYS_JJ_LE; + saddr = addr - s->paddr; switch (saddr >> 1) { case LE_RDP: switch(s->addr) { @@ -406,14 +402,12 @@ static void lance_send(void *opaque) } } -static int ledma_io_memory; - static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr) { LEDMAState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_LEDMA) >> 2; + saddr = (addr - s->addr) >> 2; if (saddr < LEDMA_REGS) return s->regs[saddr]; else @@ -425,7 +419,7 @@ static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val LEDMAState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_LEDMA) >> 2; + saddr = (addr - s->addr) >> 2; if (saddr < LEDMA_REGS) s->regs[saddr] = val; } @@ -442,29 +436,31 @@ static CPUWriteMemoryFunc *ledma_mem_write[3] = { ledma_mem_writel, }; -void lance_init(NetDriverState *nd, int irq) +void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr) { LANCEState *s; LEDMAState *led; + int lance_io_memory, ledma_io_memory; s = qemu_mallocz(sizeof(LANCEState)); if (!s) return; + s->paddr = leaddr; + s->nd = nd; + s->irq = irq; + lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_LE, 8, - lance_io_memory); + cpu_register_physical_memory(leaddr, 8, lance_io_memory); + led = qemu_mallocz(sizeof(LEDMAState)); if (!led) return; - ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led); - cpu_register_physical_memory(PHYS_JJ_LEDMA, 16, - ledma_io_memory); - - s->nd = nd; s->ledma = led; - s->irq = irq; + led->addr = ledaddr; + ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led); + cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); lance_reset(s); qemu_add_read_packet(nd, lance_can_receive, lance_receive, s); diff --git a/hw/m48t08.c b/hw/m48t08.c index c5b6e7a728..46ec665570 100644 --- a/hw/m48t08.c +++ b/hw/m48t08.c @@ -341,7 +341,7 @@ static CPUReadMemoryFunc *nvram_read[] = { }; /* Initialisation routine */ -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size) +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr) { m48t08_t *s; int i; @@ -367,7 +367,7 @@ m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size) i = 0x1fd8; s->buffer[i++] = 0x01; s->buffer[i++] = 0x80; /* Sun4m OBP */ - /* XXX: Ethernet address, etc */ + memcpy(&s->buffer[i], macaddr, 6); /* Calculate checksum */ for (i = 0x1fd8; i < 0x1fe7; i++) { diff --git a/hw/m48t08.h b/hw/m48t08.h index 2a754b698e..9b44bc0d16 100644 --- a/hw/m48t08.h +++ b/hw/m48t08.h @@ -7,6 +7,6 @@ void m48t08_write (m48t08_t *NVRAM, uint32_t val); uint32_t m48t08_read (m48t08_t *NVRAM); void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr); void m48t08_toggle_lock (m48t08_t *NVRAM, int lock); -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size); +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr); #endif /* !defined (__M48T08_H__) */ diff --git a/hw/magic-load.c b/hw/magic-load.c index 7365183da2..06a5f743af 100644 --- a/hw/magic-load.c +++ b/hw/magic-load.c @@ -1,41 +1,12 @@ -/* This is the Linux kernel elf-loading code, ported into user space */ #include "vl.h" #include "disas.h" -/* XXX: this code is not used as it is under the GPL license. Please - remove or recode it */ -//#define USE_ELF_LOADER - -#ifdef USE_ELF_LOADER -/* should probably go in elf.h */ -#ifndef ELIBBAD -#define ELIBBAD 80 -#endif - - -#define ELF_START_MMAP 0x80000000 - -#define elf_check_arch(x) ( (x) == EM_SPARC ) - #define ELF_CLASS ELFCLASS32 #define ELF_DATA ELFDATA2MSB #define ELF_ARCH EM_SPARC #include "elf.h" -/* - * This structure is used to hold the arguments that are - * used when loading binaries. - */ -struct linux_binprm { - char buf[128]; - int fd; -}; - -#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE -#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) -#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) - #ifdef BSWAP_NEEDED static void bswap_ehdr(Elf32_Ehdr *ehdr) { @@ -87,186 +58,192 @@ static void bswap_sym(Elf32_Sym *sym) bswap32s(&sym->st_size); bswap16s(&sym->st_shndx); } +#else +#define bswap_ehdr(e) do { } while (0) +#define bswap_phdr(e) do { } while (0) +#define bswap_shdr(e) do { } while (0) +#define bswap_sym(e) do { } while (0) #endif -static int prepare_binprm(struct linux_binprm *bprm) +static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type) +{ + int i, retval; + + retval = lseek(fd, ehdr->e_phoff, SEEK_SET); + if (retval < 0) + return -1; + + for (i = 0; i < ehdr->e_phnum; i++) { + retval = read(fd, phdr, sizeof(*phdr)); + if (retval < 0) + return -1; + bswap_phdr(phdr); + if (phdr->p_type == type) + return 0; + } + return -1; +} + +static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type) +{ + int i, retval; + + retval = lseek(fd, ehdr->e_shoff, SEEK_SET); + if (retval < 0) + return NULL; + + for (i = 0; i < ehdr->e_shnum; i++) { + retval = read(fd, shdr, sizeof(*shdr)); + if (retval < 0) + return NULL; + bswap_shdr(shdr); + if (shdr->sh_type == type) + return qemu_malloc(shdr->sh_size); + } + return NULL; +} + +static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab) { int retval; - memset(bprm->buf, 0, sizeof(bprm->buf)); - retval = lseek(bprm->fd, 0L, SEEK_SET); - if(retval >= 0) { - retval = read(bprm->fd, bprm->buf, 128); - } - if(retval < 0) { - perror("prepare_binprm"); - exit(-1); - /* return(-errno); */ - } - else { - return(retval); - } + retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET); + if (retval < 0) + return -1; + + retval = read(fd, shdr, sizeof(*shdr)); + if (retval < 0) + return -1; + bswap_shdr(shdr); + if (shdr->sh_type == SHT_STRTAB) + return qemu_malloc(shdr->sh_size);; + return 0; } -/* Best attempt to load symbols from this ELF object. */ -static void load_symbols(struct elfhdr *hdr, int fd) +static int read_program(int fd, struct elf_phdr *phdr, void *dst) { - unsigned int i; - struct elf_shdr sechdr, symtab, strtab; - char *strings; - - lseek(fd, hdr->e_shoff, SEEK_SET); - for (i = 0; i < hdr->e_shnum; i++) { - if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) - return; -#ifdef BSWAP_NEEDED - bswap_shdr(&sechdr); -#endif - if (sechdr.sh_type == SHT_SYMTAB) { - symtab = sechdr; - lseek(fd, hdr->e_shoff - + sizeof(sechdr) * sechdr.sh_link, SEEK_SET); - if (read(fd, &strtab, sizeof(strtab)) - != sizeof(strtab)) - return; -#ifdef BSWAP_NEEDED - bswap_shdr(&strtab); -#endif - goto found; - } - } - return; /* Shouldn't happen... */ - - found: - /* Now know where the strtab and symtab are. Snarf them. */ - disas_symtab = qemu_malloc(symtab.sh_size); - disas_strtab = strings = qemu_malloc(strtab.sh_size); - if (!disas_symtab || !disas_strtab) - return; - - lseek(fd, symtab.sh_offset, SEEK_SET); - if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size) - return; - -#ifdef BSWAP_NEEDED - for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) - bswap_sym(disas_symtab + sizeof(struct elf_sym)*i); -#endif - - lseek(fd, strtab.sh_offset, SEEK_SET); - if (read(fd, strings, strtab.sh_size) != strtab.sh_size) - return; - disas_num_syms = symtab.sh_size / sizeof(struct elf_sym); + int retval; + retval = lseek(fd, 0x4000, SEEK_SET); + if (retval < 0) + return -1; + return read(fd, dst, phdr->p_filesz); } -static int load_elf_binary(struct linux_binprm * bprm, uint8_t *addr) +static int read_section(int fd, struct elf_shdr *s, void *dst) { - struct elfhdr elf_ex; - unsigned long startaddr = addr; - int i; - struct elf_phdr * elf_ppnt; - struct elf_phdr *elf_phdata; int retval; - elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ -#ifdef BSWAP_NEEDED - bswap_ehdr(&elf_ex); -#endif - - if (elf_ex.e_ident[0] != 0x7f || - strncmp(&elf_ex.e_ident[1], "ELF",3) != 0) { - return -ENOEXEC; - } - - /* First of all, some simple consistency checks */ - if (! elf_check_arch(elf_ex.e_machine)) { - return -ENOEXEC; - } - - /* Now read in all of the header information */ - elf_phdata = (struct elf_phdr *)qemu_malloc(elf_ex.e_phentsize*elf_ex.e_phnum); - if (elf_phdata == NULL) { - return -ENOMEM; - } - - retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET); - if(retval > 0) { - retval = read(bprm->fd, (char *) elf_phdata, - elf_ex.e_phentsize * elf_ex.e_phnum); - } - - if (retval < 0) { - perror("load_elf_binary"); - exit(-1); - qemu_free (elf_phdata); - return -errno; - } - -#ifdef BSWAP_NEEDED - elf_ppnt = elf_phdata; - for (i=0; ip_type != PT_LOAD) - continue; -#if 0 - error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr), - elf_prot, - (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), - bprm->fd, - (elf_ppnt->p_offset - - TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr))); -#endif - //offset = elf_ppnt->p_offset - TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr); - offset = 0x4000; - lseek(bprm->fd, offset, SEEK_SET); - len = elf_ppnt->p_filesz + TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr); - error = read(bprm->fd, addr, len); - - if (error == -1) { - perror("mmap"); - exit(-1); - } - addr += len; - } - - qemu_free(elf_phdata); - - load_symbols(&elf_ex, bprm->fd); - - return addr-startaddr; + retval = lseek(fd, s->sh_offset, SEEK_SET); + if (retval < 0) + return -1; + retval = read(fd, dst, s->sh_size); + if (retval < 0) + return -1; + return 0; } -int elf_exec(const char * filename, uint8_t *addr) +static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type) { - struct linux_binprm bprm; - int retval; + void *dst; - retval = open(filename, O_RDONLY); - if (retval < 0) - return retval; - bprm.fd = retval; + dst = find_shdr(ehdr, fd, shdr, type); + if (!dst) + goto error; - retval = prepare_binprm(&bprm); - - if(retval>=0) { - retval = load_elf_binary(&bprm, addr); - } - return retval; + if (read_section(fd, shdr, dst)) + goto error; + return dst; + error: + qemu_free(dst); + return NULL; +} + +static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab) +{ + void *dst; + + dst = find_strtab(ehdr, fd, shdr, symtab); + if (!dst) + goto error; + + if (read_section(fd, shdr, dst)) + goto error; + return dst; + error: + qemu_free(dst); + return NULL; +} + +static void load_symbols(struct elfhdr *ehdr, int fd) +{ + struct elf_shdr symtab, strtab; + struct elf_sym *syms; + int nsyms, i; + char *str; + + /* Symbol table */ + syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB); + if (!syms) + return; + + nsyms = symtab.sh_size / sizeof(struct elf_sym); + for (i = 0; i < nsyms; i++) + bswap_sym(&syms[i]); + + /* String table */ + str = process_strtab(ehdr, fd, &strtab, &symtab); + if (!str) + goto error_freesyms; + + /* Commit */ + if (disas_symtab) + qemu_free(disas_symtab); /* XXX Merge with old symbols? */ + if (disas_strtab) + qemu_free(disas_strtab); + disas_symtab = syms; + disas_num_syms = nsyms; + disas_strtab = str; + return; + error_freesyms: + qemu_free(syms); + return; +} + +int load_elf(const char * filename, uint8_t *addr) +{ + struct elfhdr ehdr; + struct elf_phdr phdr; + int retval, fd; + + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) + goto error; + + retval = read(fd, &ehdr, sizeof(ehdr)); + if (retval < 0) + goto error; + + bswap_ehdr(&ehdr); + + if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' + || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F' + || ehdr.e_machine != EM_SPARC) + goto error; + + if (find_phdr(&ehdr, fd, &phdr, PT_LOAD)) + goto error; + retval = read_program(fd, &phdr, addr); + if (retval < 0) + goto error; + + load_symbols(&ehdr, fd); + + close(fd); + return retval; + error: + close(fd); + return -1; } -#endif int load_kernel(const char *filename, uint8_t *addr) { @@ -286,28 +263,31 @@ int load_kernel(const char *filename, uint8_t *addr) return -1; } -static char saved_kfn[1024]; -static uint32_t saved_addr; -static int magic_state; +typedef struct MAGICState { + uint32_t addr; + uint32_t saved_addr; + int magic_state; + char saved_kfn[1024]; +} MAGICState; static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr) { int ret; + MAGICState *s = opaque; - if (magic_state == 0) { -#ifdef USE_ELF_LOADER - ret = elf_exec(saved_kfn, saved_addr); -#else - ret = load_kernel(saved_kfn, (uint8_t *)saved_addr); -#endif + if (s->magic_state == 0) { + ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr); + if (ret < 0) + ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr); if (ret < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", - saved_kfn); + s->saved_kfn); } - magic_state = 1; /* No more magic */ + s->magic_state = 1; /* No more magic */ tb_flush(); + return bswap32(ret); } - return ret; + return 0; } 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] = { magic_mem_writel, }; -void magic_init(const char *kfn, int kloadaddr) +void magic_init(const char *kfn, int kloadaddr, uint32_t addr) { int magic_io_memory; + MAGICState *s; - strcpy(saved_kfn, kfn); - saved_addr = kloadaddr; - magic_state = 0; - magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, 0); - cpu_register_physical_memory(0x20000000, 4, - magic_io_memory); + s = qemu_mallocz(sizeof(MAGICState)); + if (!s) + return; + + strcpy(s->saved_kfn, kfn); + s->saved_addr = kloadaddr; + s->magic_state = 0; + s->addr = addr; + magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s); + cpu_register_physical_memory(addr, 4, magic_io_memory); } diff --git a/hw/sched.c b/hw/sched.c index c9a685d44a..2ab966de4c 100644 --- a/hw/sched.c +++ b/hw/sched.c @@ -1,5 +1,5 @@ /* - * QEMU interrupt controller & timer emulation + * QEMU interrupt controller emulation * * Copyright (c) 2003-2004 Fabrice Bellard * @@ -22,11 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" - -#define PHYS_JJ_CLOCK 0x71D00000 -#define PHYS_JJ_CLOCK1 0x71D10000 -#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ -#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ +//#define DEBUG_IRQ_COUNT /* These registers are used for sending/receiving irqs from/to * different cpu's. @@ -63,18 +59,6 @@ struct sun4m_intreg_master { /* This register is both READ and WRITE. */ unsigned int undirected_target; /* Which cpu gets undirected irqs. */ }; -/* - * Registers of hardware timer in sun4m. - */ -struct sun4m_timer_percpu { - volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */ - volatile unsigned int l14_cur_count; -}; - -struct sun4m_timer_global { - volatile unsigned int l10_timer_limit; - volatile unsigned int l10_cur_count; -}; #define SUN4M_INT_ENABLE 0x80000000 #define SUN4M_INT_E14 0x00000080 @@ -101,29 +85,25 @@ struct sun4m_timer_global { #define SUN4M_INT_VME(x) (1 << (x)) typedef struct SCHEDState { + uint32_t addr, addrg; uint32_t intreg_pending; uint32_t intreg_enabled; uint32_t intregm_pending; uint32_t intregm_enabled; - uint32_t timer_regs[2]; - uint32_t timerm_regs[2]; } SCHEDState; static SCHEDState *ps; -static int intreg_io_memory, intregm_io_memory, - timer_io_memory, timerm_io_memory; - -static void sched_reset(SCHEDState *s) -{ -} +#ifdef DEBUG_IRQ_COUNT +static uint64_t irq_count[32]; +#endif static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr) { SCHEDState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_INTR0) >> 2; + saddr = (addr - s->addr) >> 2; switch (saddr) { case 0: return s->intreg_pending; @@ -139,7 +119,7 @@ static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va SCHEDState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_INTR0) >> 2; + saddr = (addr - s->addr) >> 2; switch (saddr) { case 0: s->intreg_pending = val; @@ -172,7 +152,7 @@ static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr) SCHEDState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_INTR_G) >> 2; + saddr = (addr - s->addrg) >> 2; switch (saddr) { case 0: return s->intregm_pending; @@ -191,7 +171,7 @@ static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t v SCHEDState *s = opaque; uint32_t saddr; - saddr = (addr - PHYS_JJ_INTR_G) >> 2; + saddr = (addr - s->addrg) >> 2; switch (saddr) { case 0: s->intregm_pending = val; @@ -222,87 +202,29 @@ static CPUWriteMemoryFunc *intregm_mem_write[3] = { intregm_mem_writel, }; -static uint32_t timer_mem_readl(void *opaque, target_phys_addr_t addr) +void pic_info(void) { - SCHEDState *s = opaque; - uint32_t saddr; - - saddr = (addr - PHYS_JJ_CLOCK) >> 2; - switch (saddr) { - default: - return s->timer_regs[saddr]; - break; - } - return 0; + term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled); + term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled); } -static void timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +void irq_info(void) { - SCHEDState *s = opaque; - uint32_t saddr; +#ifndef DEBUG_IRQ_COUNT + term_printf("irq statistic code not compiled.\n"); +#else + int i; + int64_t count; - saddr = (addr - PHYS_JJ_CLOCK) >> 2; - switch (saddr) { - default: - s->timer_regs[saddr] = val; - break; + term_printf("IRQ statistics:\n"); + for (i = 0; i < 32; i++) { + count = irq_count[i]; + if (count > 0) + term_printf("%2d: %lld\n", i, count); } +#endif } -static CPUReadMemoryFunc *timer_mem_read[3] = { - timer_mem_readl, - timer_mem_readl, - timer_mem_readl, -}; - -static CPUWriteMemoryFunc *timer_mem_write[3] = { - timer_mem_writel, - timer_mem_writel, - timer_mem_writel, -}; - -static uint32_t timerm_mem_readl(void *opaque, target_phys_addr_t addr) -{ - SCHEDState *s = opaque; - uint32_t saddr; - - saddr = (addr - PHYS_JJ_CLOCK1) >> 2; - switch (saddr) { - default: - return s->timerm_regs[saddr]; - break; - } - return 0; -} - -static void timerm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ - SCHEDState *s = opaque; - uint32_t saddr; - - saddr = (addr - PHYS_JJ_CLOCK1) >> 2; - switch (saddr) { - default: - s->timerm_regs[saddr] = val; - break; - } -} - -static CPUReadMemoryFunc *timerm_mem_read[3] = { - timerm_mem_readl, - timerm_mem_readl, - timerm_mem_readl, -}; - -static CPUWriteMemoryFunc *timerm_mem_write[3] = { - timerm_mem_writel, - timerm_mem_writel, - timerm_mem_writel, -}; - -void pic_info() {} -void irq_info() {} - static const unsigned int intr_to_mask[16] = { 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -318,29 +240,29 @@ void pic_set_irq(int irq, int level) cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); } } +#ifdef DEBUG_IRQ_COUNT + if (level == 1) + irq_count[irq]++; +#endif } -void sched_init() +void sched_init(uint32_t addr, uint32_t addrg) { + int intreg_io_memory, intregm_io_memory; SCHEDState *s; s = qemu_mallocz(sizeof(SCHEDState)); if (!s) return; + s->addr = addr; + s->addrg = addrg; intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_INTR0, 3, intreg_io_memory); + cpu_register_physical_memory(addr, 3, intreg_io_memory); intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_INTR_G, 5, intregm_io_memory); + cpu_register_physical_memory(addrg, 5, intregm_io_memory); - timer_io_memory = cpu_register_io_memory(0, timer_mem_read, timer_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_CLOCK, 2, timer_io_memory); - - timerm_io_memory = cpu_register_io_memory(0, timerm_mem_read, timerm_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_CLOCK1, 2, timerm_io_memory); - - sched_reset(s); ps = s; } diff --git a/hw/sun4m.c b/hw/sun4m.c index 05dbd56a5f..80305e09c3 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -28,12 +28,26 @@ #define MMU_CONTEXT_TBL 0x00003000 #define MMU_L1PTP (MMU_CONTEXT_TBL + 0x0400) #define MMU_L2PTP (MMU_CONTEXT_TBL + 0x0800) -#define ROMVEC_DATA (MMU_CONTEXT_TBL + 0x1800) #define PROM_ADDR 0xffd04000 -#define PROM_FILENAME "proll.bin" +#define PROM_FILENAMEB "proll.bin" +#define PROM_FILENAMEE "proll.elf" +#define PROLL_MAGIC_ADDR 0x20000000 #define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */ #define PHYS_JJ_IDPROM_OFF 0x1FD8 #define PHYS_JJ_EEPROM_SIZE 0x2000 +#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ +#define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */ +#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */ +#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ +#define PHYS_JJ_LEDMA 0x78400010 /* ledma, off by 10 from unused SCSI */ +#define PHYS_JJ_LE 0x78C00000 /* LANCE, typical sun4m */ +#define PHYS_JJ_LE_IRQ 6 +#define PHYS_JJ_CLOCK 0x71D00000 +#define PHYS_JJ_CLOCK_IRQ 10 +#define PHYS_JJ_CLOCK1 0x71D10000 +#define PHYS_JJ_CLOCK1_IRQ 14 +#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ +#define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ /* TSC handling */ @@ -44,8 +58,6 @@ uint64_t cpu_get_tsc() void DMA_run() {} void SB16_run() {} -void vga_invalidate_display() {} -void vga_screen_dump(const char *filename) {} int serial_can_receive(SerialState *s) { return 0; } void serial_receive_byte(SerialState *s, int ch) {} void serial_receive_break(SerialState *s) {} @@ -59,7 +71,7 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, const char *initrd_filename) { char buf[1024]; - int ret, linux_boot, bios_size; + int ret, linux_boot; unsigned long bios_offset; linux_boot = (kernel_filename != NULL); @@ -68,32 +80,21 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, cpu_register_physical_memory(0, ram_size, 0); bios_offset = ram_size; - iommu_init(); - sched_init(); - tcx_init(ds); - lance_init(&nd_table[0], 6); - nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE); - - magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR); - -#if 0 - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME); - bios_size = get_image_size(buf); - ret = load_image(buf, phys_ram_base + bios_offset); - if (ret != bios_size) { - fprintf(stderr, "qemu: could not load prom '%s'\n", buf); - exit(1); - } - cpu_register_physical_memory(PROM_ADDR, - bios_size, bios_offset | IO_MEM_ROM); -#endif + iommu_init(PHYS_JJ_IOMMU); + sched_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G); + tcx_init(ds, PHYS_JJ_TCX_FB); + lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA); + nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE, &nd_table[0].macaddr); + timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ); + timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ); + magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR, PROLL_MAGIC_ADDR); /* We load Proll as the kernel and start it. It will issue a magic IO to load the real kernel */ if (linux_boot) { - snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAME); + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); ret = load_kernel(buf, - phys_ram_base + KERNEL_LOAD_ADDR); + phys_ram_base + KERNEL_LOAD_ADDR); if (ret < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", buf); @@ -103,28 +104,10 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, /* Setup a MMU entry for entire address space */ stl_raw(phys_ram_base + MMU_CONTEXT_TBL, (MMU_L1PTP >> 4) | 1); stl_raw(phys_ram_base + MMU_L1PTP, (MMU_L2PTP >> 4) | 1); -#if 0 - stl_raw(phys_ram_base + MMU_L1PTP + (0x50 << 2), (MMU_L2PTP >> 4) | 1); // frame buffer at 50.. -#endif + stl_raw(phys_ram_base + MMU_L1PTP + (0x01 << 2), (MMU_L2PTP >> 4) | 1); // 01.. == 00.. stl_raw(phys_ram_base + MMU_L1PTP + (0xff << 2), (MMU_L2PTP >> 4) | 1); // ff.. == 00.. + stl_raw(phys_ram_base + MMU_L1PTP + (0xf0 << 2), (MMU_L2PTP >> 4) | 1); // f0.. == 00.. /* 3 = U:RWX S:RWX */ stl_raw(phys_ram_base + MMU_L2PTP, (3 << PTE_ACCESS_SHIFT) | 2); -#if 0 - stl_raw(phys_ram_base + MMU_L2PTP + 0x84, (PHYS_JJ_TCX_FB >> 4) \ - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf - stl_raw(phys_ram_base + MMU_L2PTP + 0x88, (PHYS_JJ_TCX_FB >> 4) \ - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf - stl_raw(phys_ram_base + MMU_L2PTP + 0x140, (PHYS_JJ_TCX_FB >> 4) \ - | (3 << PTE_ACCESS_SHIFT) | 2); // frame buf - // "Empirical constant" - stl_raw(phys_ram_base + ROMVEC_DATA, 0x10010407); - - // Version: V3 prom - stl_raw(phys_ram_base + ROMVEC_DATA + 4, 3); - - stl_raw(phys_ram_base + ROMVEC_DATA + 0x1c, ROMVEC_DATA+0x400); - stl_raw(phys_ram_base + ROMVEC_DATA + 0x400, ROMVEC_DATA+0x404); - stl_raw(phys_ram_base + ROMVEC_DATA + 0x404, 0x81c3e008); // retl - stl_raw(phys_ram_base + ROMVEC_DATA + 0x408, 0x01000000); // nop -#endif + stl_raw(phys_ram_base + MMU_L2PTP, ((0x01 << PTE_PPN_SHIFT) >> 4 ) | (3 << PTE_ACCESS_SHIFT) | 2); } diff --git a/hw/tcx.c b/hw/tcx.c index d9b91c68ff..7f979946fc 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -23,9 +23,6 @@ */ #include "vl.h" -#define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */ -#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */ - #define MAXX 1024 #define MAXY 768 #define XSZ (8*80) @@ -33,38 +30,32 @@ #define XOFF (MAXX-XSZ) #define YOFF (MAXY-YSZ) -#define DEBUG_VGA_MEM - typedef struct TCXState { - uint8_t *vram_ptr; - unsigned long vram_offset; - unsigned int vram_size; + uint32_t addr; DisplayState *ds; + uint8_t *vram; } TCXState; static TCXState *ts; -static int tcx_io_memory; - void vga_update_display() { dpy_update(ts->ds, 0, 0, XSZ, YSZ); } +void vga_invalidate_display() {} + static uint32_t tcx_mem_readb(void *opaque, target_phys_addr_t addr) { TCXState *s = opaque; uint32_t saddr; unsigned int x, y; - char *sptr; - saddr = addr - PHYS_JJ_TCX_FB - YOFF*MAXX - XOFF; + saddr = addr - s->addr - YOFF*MAXX - XOFF; y = saddr / MAXX; x = saddr - y * MAXX; - if (x < MAXX && y < MAXY) { - sptr = s->ds->data; - if (sptr) - return sptr[y * s->ds->linesize + x*4]; + if (x < XSZ && y < YSZ) { + return s->vram[y * XSZ + x]; } return 0; } @@ -99,7 +90,6 @@ static uint32_t tcx_mem_readl(void *opaque, target_phys_addr_t addr) return v; } -/* called for accesses between 0xa0000 and 0xc0000 */ static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { TCXState *s = opaque; @@ -107,17 +97,24 @@ static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) unsigned int x, y; char *sptr; - saddr = addr - PHYS_JJ_TCX_FB - YOFF*MAXX - XOFF; + saddr = addr - s->addr - YOFF*MAXX - XOFF; y = saddr / MAXX; x = saddr - y * MAXX; - if (x < MAXX && y < MAXY) { + if (x < XSZ && y < YSZ) { sptr = s->ds->data; if (sptr) { - sptr[y * s->ds->linesize + x*4] = val; - sptr[y * s->ds->linesize + x*4+1] = val; - sptr[y * s->ds->linesize + x*4+2] = val; - cpu_physical_memory_set_dirty(addr); + if (s->ds->depth == 24 || s->ds->depth == 32) { + /* XXX need to do CLUT translation */ + sptr[y * s->ds->linesize + x*4] = val & 0xff; + sptr[y * s->ds->linesize + x*4+1] = val & 0xff; + sptr[y * s->ds->linesize + x*4+2] = val & 0xff; + } + else if (s->ds->depth == 8) { + sptr[y * s->ds->linesize + x] = val & 0xff; + } } + cpu_physical_memory_set_dirty(addr); + s->vram[y * XSZ + x] = val & 0xff; } } @@ -159,18 +156,52 @@ static CPUWriteMemoryFunc *tcx_mem_write[3] = { tcx_mem_writel, }; -void tcx_init(DisplayState *ds) +void tcx_init(DisplayState *ds, uint32_t addr) { TCXState *s; + int tcx_io_memory; s = qemu_mallocz(sizeof(TCXState)); if (!s) return; s->ds = ds; + s->addr = addr; ts = s; tcx_io_memory = cpu_register_io_memory(0, tcx_mem_read, tcx_mem_write, s); - cpu_register_physical_memory(PHYS_JJ_TCX_FB, 0x100000, + cpu_register_physical_memory(addr, 0x100000, tcx_io_memory); + s->vram = qemu_mallocz(XSZ*YSZ); dpy_resize(s->ds, XSZ, YSZ); } +void vga_screen_dump(const char *filename) +{ + TCXState *s = ts; + FILE *f; + uint8_t *d, *d1; + unsigned int v; + int y, x; + + f = fopen(filename, "wb"); + if (!f) + return -1; + fprintf(f, "P6\n%d %d\n%d\n", + XSZ, YSZ, 255); + d1 = s->vram; + for(y = 0; y < YSZ; y++) { + d = d1; + for(x = 0; x < XSZ; x++) { + v = *d; + fputc((v) & 0xff, f); + fputc((v) & 0xff, f); + fputc((v) & 0xff, f); + d++; + } + d1 += XSZ; + } + fclose(f); + return; +} + + + diff --git a/monitor.c b/monitor.c index 15b54d3e71..c39f3b2391 100644 --- a/monitor.c +++ b/monitor.c @@ -952,11 +952,7 @@ static int monitor_get_tbl (struct MonitorDef *md, int val) #if defined(TARGET_SPARC) static int monitor_get_psr (struct MonitorDef *md, int val) { - return (0<<28) | (4<<24) | cpu_single_env->psr \ - | (cpu_single_env->psrs? PSR_S : 0) \ - | (cpu_single_env->psrs? PSR_PS : 0) \ - | (cpu_single_env->psret? PSR_ET : 0) \ - | cpu_single_env->cwp; + return GET_PSR(cpu_single_env); } static int monitor_get_reg(struct MonitorDef *md, int val) diff --git a/pc-bios/README b/pc-bios/README index 31f91f3cef..a10a9f0dfa 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -6,3 +6,8 @@ - The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is available at http://site.voila.fr/jmayer/OpenHackWare/index.htm. + +- Proll is a GPL'd boot PROM for Sparc JavaStations + (http://people.redhat.com/zaitcev/linux/). + Applying proll.patch allows circumventing some bugs and enables + faster kernel load through a hack. diff --git a/pc-bios/proll.bin b/pc-bios/proll.bin new file mode 100644 index 0000000000000000000000000000000000000000..0489cc245fc524bb89eb36582304617ec4ca5b59 GIT binary patch literal 56856 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, 1); -} -#endif - #if !defined(CONFIG_USER_ONLY) #define MMUSUFFIX _mmu @@ -258,7 +240,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; env->mmuregs[4] = address; /* Fault address register */ - if (env->mmuregs[0] & MMU_NF) // No fault + if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault return 0; env->exception_index = exception; @@ -306,7 +288,7 @@ void do_interrupt(int intno, int is_int, int error_code, fprintf(logfile, "%6d: v=%02x e=%04x i=%d pc=%08x npc=%08x SP=%08x\n", count, intno, error_code, is_int, env->pc, - env->npc, env->gregs[7]); + env->npc, env->regwptr[6]); #if 0 cpu_sparc_dump_state(env, logfile, 0); { diff --git a/target-sparc/op.c b/target-sparc/op.c index a2d37469d4..042fd6199a 100644 --- a/target-sparc/op.c +++ b/target-sparc/op.c @@ -474,92 +474,6 @@ void OPPROTO op_sra(void) T0 = ((int32_t) T0) >> T1; } -#if 0 -void OPPROTO op_st(void) -{ - stl((void *) T0, T1); -} - -void OPPROTO op_stb(void) -{ - stb((void *) T0, T1); -} - -void OPPROTO op_sth(void) -{ - stw((void *) T0, T1); -} - -void OPPROTO op_std(void) -{ - stl((void *) T0, T1); - stl((void *) (T0 + 4), T2); -} - -void OPPROTO op_ld(void) -{ - T1 = ldl((void *) T0); -} - -void OPPROTO op_ldub(void) -{ - T1 = ldub((void *) T0); -} - -void OPPROTO op_lduh(void) -{ - T1 = lduw((void *) T0); -} - -void OPPROTO op_ldsb(void) -{ - T1 = ldsb((void *) T0); -} - -void OPPROTO op_ldsh(void) -{ - T1 = ldsw((void *) T0); -} - -void OPPROTO op_ldstub(void) -{ - T1 = ldub((void *) T0); - stb((void *) T0, 0xff); /* XXX: Should be Atomically */ -} - -void OPPROTO op_swap(void) -{ - unsigned int tmp = ldl((void *) T0); - stl((void *) T0, T1); /* XXX: Should be Atomically */ - T1 = tmp; -} - -void OPPROTO op_ldd(void) -{ - T1 = ldl((void *) T0); - T0 = ldl((void *) (T0 + 4)); -} - -void OPPROTO op_stf(void) -{ - stfl((void *) T0, FT0); -} - -void OPPROTO op_stdf(void) -{ - stfq((void *) T0, DT0); -} - -void OPPROTO op_ldf(void) -{ - FT0 = ldfl((void *) T0); -} - -void OPPROTO op_lddf(void) -{ - DT0 = ldfq((void *) T0); -} -#else /* Load and store */ #define MEMSUFFIX _raw #include "op_mem.h" @@ -570,19 +484,16 @@ void OPPROTO op_lddf(void) #define MEMSUFFIX _kernel #include "op_mem.h" #endif -#endif void OPPROTO op_ldfsr(void) { env->fsr = *((uint32_t *) &FT0); - FORCE_RET(); + helper_ldfsr(); } void OPPROTO op_stfsr(void) { *((uint32_t *) &FT0) = env->fsr; - helper_stfsr(); - FORCE_RET(); } void OPPROTO op_wry(void) @@ -609,16 +520,17 @@ void OPPROTO op_wrwim(void) void OPPROTO op_rdpsr(void) { T0 = GET_PSR(env); - FORCE_RET(); } void OPPROTO op_wrpsr(void) { + int cwp; env->psr = T0 & ~PSR_ICC; env->psrs = (T0 & PSR_S)? 1 : 0; env->psrps = (T0 & PSR_PS)? 1 : 0; env->psret = (T0 & PSR_ET)? 1 : 0; - env->cwp = (T0 & PSR_CWP); + cwp = (T0 & PSR_CWP) & (NWINDOWS - 1); + set_cwp(cwp); FORCE_RET(); } diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 253bcff6f1..909639af0f 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -104,6 +104,27 @@ void OPPROTO helper_st_asi(int asi, int size, int sign) } } +#if 0 +void do_ldd_raw(uint32_t addr) +{ + T1 = ldl_raw((void *) addr); + T0 = ldl_raw((void *) (addr + 4)); +} + +#if !defined(CONFIG_USER_ONLY) +void do_ldd_user(uint32_t addr) +{ + T1 = ldl_user((void *) addr); + T0 = ldl_user((void *) (addr + 4)); +} +void do_ldd_kernel(uint32_t addr) +{ + T1 = ldl_kernel((void *) addr); + T0 = ldl_kernel((void *) (addr + 4)); +} +#endif +#endif + void OPPROTO helper_rett() { int cwp; @@ -116,7 +137,7 @@ void OPPROTO helper_rett() env->psrs = env->psrps; } -void helper_stfsr(void) +void helper_ldfsr(void) { switch (env->fsr & FSR_RD_MASK) { case FSR_RD_NEAREST: diff --git a/target-sparc/op_mem.h b/target-sparc/op_mem.h index 9c839a0047..2ae74f2cef 100644 --- a/target-sparc/op_mem.h +++ b/target-sparc/op_mem.h @@ -43,8 +43,12 @@ void OPPROTO glue(op_swap, MEMSUFFIX)(void) void OPPROTO glue(op_ldd, MEMSUFFIX)(void) { +#if 1 T1 = glue(ldl, MEMSUFFIX)((void *) T0); T0 = glue(ldl, MEMSUFFIX)((void *) (T0 + 4)); +#else + glue(do_ldd, MEMSUFFIX)(T0); +#endif } /*** Floating-point store ***/ diff --git a/tests/Makefile b/tests/Makefile index 1142deaede..c0ee7b2a03 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -include ../config-host.mak +-include ../config-host.mak CFLAGS=-Wall -O2 -g LDFLAGS= diff --git a/vl.h b/vl.h index 8ebb268d21..f25bbaa5cf 100644 --- a/vl.h +++ b/vl.h @@ -673,20 +673,23 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, const char *initrd_filename); /* iommu.c */ -void iommu_init(); +void iommu_init(uint32_t addr); uint32_t iommu_translate(uint32_t addr); /* lance.c */ -void lance_init(NetDriverState *nd, int irq); +void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr); /* tcx.c */ -void tcx_init(DisplayState *ds); +void tcx_init(DisplayState *ds, uint32_t addr); /* sched.c */ void sched_init(); /* magic-load.c */ -void magic_init(const char *kfn, int kloadaddr); +void magic_init(const char *kfn, int kloadaddr, uint32_t addr); + +/* timer.c */ +void timer_init(uint32_t addr, int irq); /* NVRAM helpers */ #include "hw/m48t59.h"