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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

%Musg-OVd`wpeJ@!J6%C}xm! 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 literal 0 HcmV?d00001 diff --git a/pc-bios/proll.patch b/pc-bios/proll.patch new file mode 100644 index 0000000000..b0860e26f4 --- /dev/null +++ b/pc-bios/proll.patch @@ -0,0 +1,50 @@ +diff -ru proll_18.orig/mrcoffee/main.c proll_18/mrcoffee/main.c +--- proll_18.orig/mrcoffee/main.c 2002-09-13 16:16:59.000000000 +0200 ++++ proll_18/mrcoffee/main.c 2004-09-26 11:52:23.000000000 +0200 +@@ -101,6 +101,7 @@ + le_probe(); + init_net(); + ++#ifdef ORIG + #if 0 /* RARP */ + if (rarp() != 0) fatal(); + /* printrarp(); */ +@@ -117,13 +118,20 @@ + xtoa(myipaddr, fname, 8); + if (load(boot_rec.bp_siaddr, fname) != 0) fatal(); + #endif ++#endif + + romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas); + + printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n", + PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024, + (int)cio.start, (int)cio.curp); ++#ifdef ORIG + set_timeout(5); while (!chk_timeout()) { } /* P3: let me read */ ++#else ++ printk("loading kernel:"); ++ i = ld_bypass(0x20000000); ++ printk(" done, size %d\n", i); ++#endif + + { + void (*entry)(void *, int) = (void (*)(void*, int)) LOADBASE; +diff -ru proll_18.orig/mrcoffee/openprom.c proll_18/mrcoffee/openprom.c +--- proll_18.orig/mrcoffee/openprom.c 2002-09-13 16:17:03.000000000 +0200 ++++ proll_18/mrcoffee/openprom.c 2004-09-21 21:27:16.000000000 +0200 +@@ -144,10 +144,14 @@ + }; + + static int cpu_nctx = NCTX_SWIFT; ++static int cpu_cache_line_size = 0x20; ++static int cpu_cache_nlines = 0x200; + static struct property propv_cpu[] = { + {"name", "STP1012PGA", sizeof("STP1012PGA") }, + {"device_type", "cpu", 4 }, + {"mmu-nctx", (char*)&cpu_nctx, sizeof(int)}, ++ {"cache-line-size", (char*)&cpu_cache_line_size, sizeof(int)}, ++ {"cache-nlines", (char*)&cpu_cache_nlines, sizeof(int)}, + {NULL, NULL, -1} + }; + diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 4c23b924a4..03698df21f 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -76,6 +76,7 @@ #define PTE_ENTRYTYPE_MASK 3 #define PTE_ACCESS_MASK 0x1c #define PTE_ACCESS_SHIFT 2 +#define PTE_PPN_SHIFT 7 #define PTE_ADDR_MASK 0xffffff00 #define PG_ACCESSED_BIT 5 diff --git a/target-sparc/exec.h b/target-sparc/exec.h index f9fcf532ad..cea9616b36 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h @@ -23,13 +23,16 @@ void helper_flush(target_ulong addr); void helper_ld_asi(int asi, int size, int sign); void helper_st_asi(int asi, int size, int sign); void helper_rett(void); -void helper_stfsr(void); +void helper_ldfsr(void); void set_cwp(int new_cwp); void do_fabss(void); void do_fsqrts(void); void do_fsqrtd(void); void do_fcmps(void); void do_fcmpd(void); +void do_ldd_kernel(uint32_t addr); +void do_ldd_user(uint32_t addr); +void do_ldd_raw(uint32_t addr); void do_interrupt(int intno, int is_int, int error_code, unsigned int next_eip, int is_hw); void raise_exception_err(int exception_index, int error_code); diff --git a/target-sparc/helper.c b/target-sparc/helper.c index ae70595c5f..63d08e77d5 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -21,19 +21,10 @@ #define DEBUG_PCALL -#if 0 -#define raise_exception_err(a, b)\ -do {\ - fprintf(logfile, "raise_exception line=%d\n", __LINE__);\ - (raise_exception_err)(a, b);\ -} while (0) -#endif - /* Sparc MMU emulation */ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, int is_user, int is_softmmu); - /* thread support */ spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; @@ -48,15 +39,6 @@ void cpu_unlock(void) spin_unlock(&global_cpu_lock); } -#if 0 -void cpu_loop_exit(void) -{ - /* NOTE: the register at this point must be saved by hand because - longjmp restore them */ - longjmp(env->jmp_env, 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"