* Concerning Qemu SH4
@ 2008-11-08 0:01 Kristoffer Ericson
2008-11-08 15:28 ` takasi-y
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Kristoffer Ericson @ 2008-11-08 0:01 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 437 bytes --]
Greetings,
Oki, gotten it to work now. Whats left is putting some sort
of harddrive file there. I've created an loop file but
can't seem to get it going.
As any sh kernel it uses scsi emulation (hda->sda) while
qemu expects harddrives on hda/b/c.
I'm also missing something with the initrd as it
constantly claims that the initrd expands beyond
the memory boundry.
--
Kristoffer Ericson <kristoffer.ericson@gmail.com>
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Concerning Qemu SH4
2008-11-08 0:01 Concerning Qemu SH4 Kristoffer Ericson
@ 2008-11-08 15:28 ` takasi-y
2008-11-08 19:37 ` Kristoffer Ericson
2008-11-08 19:42 ` Kristoffer Ericson
2 siblings, 0 replies; 4+ messages in thread
From: takasi-y @ 2008-11-08 15:28 UTC (permalink / raw)
To: linux-sh
Hi,
> Oki, gotten it to work now. Whats left is putting some sort
> of harddrive file there. I've created an loop file but
> can't seem to get it going.
Have you applied all patches on ML?
Otherwise it doesn't support hard disk.
QEMU repository is being maintained very slowly.
There always many patches left on ML waiting for being merged.
Now, following patches are pending.
http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg00970.html
This must be applied. Otherwise it will be crashed frequently.
http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01246.html
http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01247.html
http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01248.html
These three are needed use to use HDD.
http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00118.html
http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00119.html
These two are needed to use network.
Some of them can't be applied cleanly, because other patch has been
applied after I posted them. Please edit them manually.
> I'm also missing something with the initrd as it
> constantly claims that the initrd expands beyond
> the memory boundry.
Current code doesn't support --initrd nor --append.
Only --kernel works. Use initramfs and initial command line.
/yoshii
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Concerning Qemu SH4
2008-11-08 0:01 Concerning Qemu SH4 Kristoffer Ericson
2008-11-08 15:28 ` takasi-y
@ 2008-11-08 19:37 ` Kristoffer Ericson
2008-11-08 19:42 ` Kristoffer Ericson
2 siblings, 0 replies; 4+ messages in thread
From: Kristoffer Ericson @ 2008-11-08 19:37 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1.1: Type: text/plain, Size: 23823 bytes --]
On Sun, 9 Nov 2008 00:28:35 +0900 (JST)
takasi-y@ops.dti.ne.jp wrote:
> Hi,
>
> > Oki, gotten it to work now. Whats left is putting some sort
> > of harddrive file there. I've created an loop file but
> > can't seem to get it going.
> Have you applied all patches on ML?
> Otherwise it doesn't support hard disk.
> QEMU repository is being maintained very slowly.
> There always many patches left on ML waiting for being merged.
>
> Now, following patches are pending.
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg00970.html
> This must be applied. Otherwise it will be crashed frequently.
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01246.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01247.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01248.html
> These three are needed use to use HDD.
> http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00118.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00119.html
> These two are needed to use network.
Great!
>
> Some of them can't be applied cleanly, because other patch has been
> applied after I posted them. Please edit them manually.
>
I've edited them and finally gotten everything to compile (without errors/warnings).
BUT I get segmentation fault at startup, I'm thinking it could be related
to me compiling with 4.1.x, so I'm going to give it a try with 3.4.x.
I've attached the up-to-date diff (and also below for everyone else).
Note that the sh_pci.c is just a regular file so it's not an patch.
> > I'm also missing something with the initrd as it
> > constantly claims that the initrd expands beyond
> > the memory boundry.
> Current code doesn't support --initrd nor --append.
> Only --kernel works. Use initramfs and initial command line.
>
> /yoshii
/*
* SuperH on-chip PCIC emulation.
*
* Copyright (c) 2008 Takashi YOSHII
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
eal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "sh.h"
#include "pci.h"
typedef struct {
PCIBus *bus;
PCIDevice *dev;
uint32_t regbase;
uint32_t iopbase;
uint32_t membase;
uint32_t par;
uint32_t mbr;
uint32_t iobr;
} SHPCIC;
static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
{
SHPCIC *pcic = p;
addr -= pcic->regbase;
switch(addr) {
case 0 ... 0xff: *(uint32_t*)(pcic->dev->config + addr) = val;
case 0x1c0: pcic->par = val; break;
case 0x1c4: pcic->mbr = val; break;
case 0x1c8: pcic->iobr = val; break;
case 0x220: pci_data_write(pcic->bus, pcic->par, val, 4);
}
}
static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
{
SHPCIC *pcic = p;
addr -= pcic->regbase;
switch(addr) {
case 0 ... 0xff: return *(uint32_t*)(pcic->dev->config + addr);
case 0x1c0: return pcic->par;
case 0x220: return pci_data_read(pcic->bus, pcic->par, 4);
}
return 0;
}
static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
uint32_t val, int size)
{
pci_data_write(pcic->bus, addr - pcic->membase + pcic->mbr, val, size);
}
static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
int size)
{
return pci_data_read(pcic->bus, addr - pcic->membase + pcic->mbr, size);
}
static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 1);
}
static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 2);
}
static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 4);
}
static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 1);
}
static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 2);
}
static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 4);
}
static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
{
return addr - pcic->iopbase + pcic->iobr;
}
static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outb(NULL, sh_pci_addr2port(p, addr), val);
}
static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outw(NULL, sh_pci_addr2port(p, addr), val);
}
static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outl(NULL, sh_pci_addr2port(p, addr), val);
}
static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
{
return cpu_inb(NULL, sh_pci_addr2port(p, addr));
}
static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
{
return cpu_inw(NULL, sh_pci_addr2port(p, addr));
}
static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
{
return cpu_inl(NULL, sh_pci_addr2port(p, addr));
}
typedef struct {
CPUReadMemoryFunc *r[3];
CPUWriteMemoryFunc *w[3];
} MemOp;
static MemOp sh_pci_reg = {
{ NULL, NULL, sh_pci_reg_read },
{ NULL, NULL, sh_pci_reg_write },
};
static MemOp sh_pci_mem = {
{ sh_pci_readb, sh_pci_readw, sh_pci_readl },
{ sh_pci_writeb, sh_pci_writew, sh_pci_writel },
};
static MemOp sh_pci_iop = {
{ sh_pci_inb, sh_pci_inw, sh_pci_inl },
{ sh_pci_outb, sh_pci_outw, sh_pci_outl },
};
PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq)
{
SHPCIC *p;
int mem, reg, iop;
p = qemu_mallocz(sizeof(SHPCIC));
p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
-1, NULL, NULL);
p->regbase = 0x1e200000;
p->iopbase = 0x1e240000;
p->membase = 0xfd000000;
reg = cpu_register_io_memory(0, sh_pci_reg.r, sh_pci_reg.w, p);
mem = cpu_register_io_memory(0, sh_pci_mem.r, sh_pci_mem.w, p);
iop = cpu_register_io_memory(0, sh_pci_iop.r, sh_pci_iop.w, p);
cpu_register_physical_memory(p->regbase, 0x224, reg);
cpu_register_physical_memory(p->iopbase, 0x40000, iop);
cpu_register_physical_memory(p->membase, 0x1000000, mem);
p->dev->config[0x00] = 0x54; // HITACHI
p->dev->config[0x01] = 0x10; //
p->dev->config[0x02] = 0x0e; // SH7751R
p->dev->config[0x03] = 0x35; //
p->dev->config[0x04] = 0x80;
p->dev->config[0x05] = 0x00;
p->dev->config[0x06] = 0x90;
p->dev->config[0x07] = 0x02;
return p->bus;
}
Index: target-sh4/helper.c
===================================================================
--- target-sh4/helper.c (revision 5646)
+++ target-sh4/helper.c (working copy)
@@ -359,14 +359,13 @@
int *prot, target_ulong address,
int rw, int access_type)
{
- int use_asid, is_code, n;
+ int use_asid, n;
tlb_t *matching = NULL;
use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
- is_code = env->pc == address; /* Hack */
/* Use a hack to find if this is an instruction or data access */
- if (env->pc == address && !(rw & PAGE_WRITE)) {
+ if (rw == 2) {
n = find_itlb_entry(env, address, use_asid, 1);
if (n >= 0) {
matching = &env->itlb[n];
@@ -382,13 +381,13 @@
switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
case 0: /* 000 */
case 2: /* 010 */
- n = (rw & PAGE_WRITE) ? MMU_DTLB_VIOLATION_WRITE :
+ n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
MMU_DTLB_VIOLATION_READ;
break;
case 1: /* 001 */
case 4: /* 100 */
case 5: /* 101 */
- if (rw & PAGE_WRITE)
+ if (rw == 1)
n = MMU_DTLB_VIOLATION_WRITE;
else
*prot = PAGE_READ;
@@ -396,11 +395,11 @@
case 3: /* 011 */
case 6: /* 110 */
case 7: /* 111 */
- *prot = rw & (PAGE_READ | PAGE_WRITE);
+ *prot = (rw == 1) ? PAGE_WRITE : PAGE_READ;
break;
}
} else if (n == MMU_DTLB_MISS) {
- n = (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
+ n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
MMU_DTLB_MISS_READ;
}
}
@@ -426,8 +425,12 @@
&& (address < 0xe0000000 || address > 0xe4000000)) {
/* Unauthorized access in user mode (only store queues are available) */
fprintf(stderr, "Unauthorized access\n");
- return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
- MMU_DTLB_MISS_READ;
+ if (rw == 0)
+ return MMU_DTLB_MISS_READ;
+ else if (rw == 1)
+ return MMU_DTLB_MISS_WRITE;
+ else
+ return MMU_ITLB_MISS;
}
if (address >= 0x80000000 && address < 0xc0000000) {
/* Mask upper 3 bits for P1 and P2 areas */
@@ -465,27 +468,6 @@
target_ulong physical, page_offset, page_size;
int prot, ret, access_type;
- switch (rw) {
- case 0:
- rw = PAGE_READ;
- break;
- case 1:
- rw = PAGE_WRITE;
- break;
- case 2: /* READ_ACCESS_TYPE == 2 defined in softmmu_template.h */
- rw = PAGE_READ;
- break;
- default:
- /* fatal error */
- assert(0);
- }
-
- /* XXXXX */
-#if 0
- fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
- __func__, env->pc, address, rw, mmu_idx, is_softmmu);
-#endif
-
access_type = ACCESS_INT;
ret =
get_physical_address(env, &physical, &prot, address, rw,
@@ -537,7 +519,7 @@
target_ulong physical;
int prot;
- get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
+ get_physical_address(env, &physical, &prot, addr, 0, 0);
return physical;
}
Index: Makefile.target
===================================================================
--- Makefile.target (revision 5646)
+++ Makefile.target (working copy)
@@ -738,6 +738,7 @@
ifeq ($(TARGET_BASE_ARCH), sh4)
OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sm501.o serial.o
+OBJS+= ide.o sh_pci.o
endif
ifeq ($(TARGET_BASE_ARCH), m68k)
OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
Index: hw/r2d.c
===================================================================
--- hw/r2d.c (revision 5646)
+++ hw/r2d.c (working copy)
@@ -28,19 +28,24 @@
#include "devices.h"
#include "sysemu.h"
#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sh7750_regs.h"
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
#define SM501_VRAM_SIZE 0x800000
+#define PA_IRLMSK 0x00
#define PA_POWOFF 0x30
#define PA_VERREG 0x32
#define PA_OUTPORT 0x36
typedef struct {
target_phys_addr_t base;
-
+ /*register */
+ uint16_t irlmsk;
uint16_t bcr;
uint16_t irlmon;
uint16_t cfctl;
@@ -62,8 +67,54 @@
uint16_t inport;
uint16_t outport;
uint16_t bverreg;
+
+ /* output_pin */
+ qemu_irq irl;
+
} r2d_fpga_t;
+enum r2d_fgpa_irq {
+ PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
+ SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
+ NR_IRQS
+};
+
+static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
+ [CF_IDE] = { 1, 1<<9 },
+ [CF_CD] = { 2, 1<<8 },
+ [PCI_INTA] = { 9, 1<<14 },
+ [PCI_INTB] = {10, 1<<13 },
+ [PCI_INTC] = { 3, 1<<12 },
+ [PCI_INTD] = { 0, 1<<11 },
+ [SM501] = { 4, 1<<10 },
+ [KEY] = { 5, 1<<6 },
+ [RTC_A] = { 6, 1<<5 },
+ [RTC_T] = { 7, 1<<4 },
+ [SDCARD] = { 8, 1<<7 },
+ [EXT] = {11, 1<<0 },
+ [TP] = {12, 1<<15 },
+};
+
+static void update_irl(r2d_fpga_t *fpga)
+{
+ int i, irl = 15;
+ for (i = 0; i < NR_IRQS; i++)
+ if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
+ if (irqtab[i].irl < irl)
+ irl = irqtab[i].irl;
+ qemu_set_irq(fpga->irl, irl ^ 15);
+}
+
+static void r2d_fpga_irq_set(void *opaque, int n, int level)
+{
+ r2d_fpga_t *fpga = opaque;
+ if (level)
+ fpga->irlmon |= irqtab[n].msk;
+ else
+ fpga->irlmon &= ~irqtab[n].msk;
+ update_irl(fpga);
+}
+
static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
{
r2d_fpga_t *s = opaque;
@@ -71,6 +122,8 @@
addr -= s->base;
switch (addr) {
+ case PA_IRLMSK:
+ return s->irlmsk;
case PA_OUTPORT:
return s->outport;
case PA_POWOFF:
@@ -90,6 +143,10 @@
addr -= s->base;
switch (addr) {
+ case PA_IRLMSK:
+ s->irlmsk = value;
+ update_irl(s);
+ break;
case PA_OUTPORT:
s->outport = value;
break;
@@ -114,21 +171,35 @@
NULL,
};
-static void r2d_fpga_init(target_phys_addr_t base)
+static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
{
int iomemtype;
r2d_fpga_t *s;
s = qemu_mallocz(sizeof(r2d_fpga_t));
if (!s)
- return;
+ return NULL;
+ s->irl = irl;
+
s->base = base;
iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
r2d_fpga_writefn, s);
cpu_register_physical_memory(base, 0x40, iomemtype);
+ return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
}
+static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
+{
+ qemu_set_irq(p[n], l);
+}
+
+static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
+{
+ const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD };
+ return intx[d->devfn>>3];
+}
+
static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
const char *boot_device, DisplayState * ds,
const char *kernel_filename, const char *kernel_cmdline,
@@ -136,6 +207,10 @@
{
CPUState *env;
struct SH7750State *s;
+ qemu_irq *irq;
+ PCIBus *pci;
+ int i;
+
ram_addr_t sdram_addr, sm501_vga_ram_addr;
if (!cpu_model)
@@ -151,14 +226,24 @@
sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
/* Register peripherals */
- r2d_fpga_init(0x04000000);
+ irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
+ pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
s = sh7750_init(env);
sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
serial_hds[2]);
+
+ mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+ drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
+
/* Todo: register on board registers */
{
int kernel_size;
+ /* initialization which should be done by firmware */
+ uint32_t bcr1 = 1<<3; // cs3 SDRAM
+ uint16_t bcr2 = 3<<(3*2); // cs3 32bit
+ cpu_physical_memory_write(SH7750_BCR1_A7, &bcr1, 4);
+ cpu_physical_memory_write(SH7750_BCR2_A7, &bcr2, 2);
kernel_size = load_image(kernel_filename, phys_ram_base);
Index: hw/sh.h
===================================================================
--- hw/sh.h (revision 5646)
+++ hw/sh.h (working copy)
@@ -42,7 +42,14 @@
struct intc_source *tei_source,
struct intc_source *bri_source);
+/* sh7750.c */
+qemu_irq sh7750_irl(struct SH7750State *s);
+
/* tc58128.c */
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
+/* ide.c */
+void mmio_ide_init(target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1);
#endif
Index: hw/sh7750.c
===================================================================
--- hw/sh7750.c (revision 5646)
+++ hw/sh7750.c (working copy)
@@ -41,6 +41,8 @@
/* Peripheral frequency in Hz */
uint32_t periph_freq;
/* SDRAM controller */
+ uint32_t bcr1;
+ uint32_t bcr2;
uint16_t rfcr;
/* IO ports */
uint16_t gpioic;
@@ -208,6 +210,8 @@
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR2_A7:
+ return s->bcr2;
case SH7750_FRQCR_A7:
return 0;
case SH7750_RFCR_A7:
@@ -231,6 +235,15 @@
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR1_A7:
+ return s->bcr1;
+ case SH7750_BCR4_A7:
+ case SH7750_WCR1_A7:
+ case SH7750_WCR2_A7:
+ case SH7750_WCR3_A7:
+ case SH7750_MCR_A7:
+ ignore_access("long read", addr);
+ return 0;
case SH7750_MMUCR_A7:
return s->cpu->mmucr;
case SH7750_PTEH_A7:
@@ -285,6 +298,8 @@
switch (addr) {
/* SDRAM controller */
case SH7750_BCR2_A7:
+ s->bcr2 = mem_value;
+ return;
case SH7750_BCR3_A7:
case SH7750_RTCOR_A7:
case SH7750_RTCNT_A7:
@@ -331,6 +346,8 @@
switch (addr) {
/* SDRAM controller */
case SH7750_BCR1_A7:
+ s->bcr1 = mem_value;
+ return;
case SH7750_BCR4_A7:
case SH7750_WCR1_A7:
case SH7750_WCR2_A7:
@@ -412,6 +429,8 @@
UNUSED = 0,
/* interrupt sources */
+ IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
+ IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
HUDI, GPIOI,
DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
@@ -428,10 +447,34 @@
/* interrupt groups */
DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
-
+ IRL,
NR_SOURCES,
};
+static struct intc_vect vectors_irl[] = {
+ INTC_VECT(IRL_0, 0x200),
+ INTC_VECT(IRL_1, 0x220),
+ INTC_VECT(IRL_2, 0x240),
+ INTC_VECT(IRL_3, 0x260),
+ INTC_VECT(IRL_4, 0x280),
+ INTC_VECT(IRL_5, 0x2a0),
+ INTC_VECT(IRL_6, 0x2c0),
+ INTC_VECT(IRL_7, 0x2e0),
+ INTC_VECT(IRL_8, 0x300),
+ INTC_VECT(IRL_9, 0x320),
+ INTC_VECT(IRL_A, 0x340),
+ INTC_VECT(IRL_B, 0x360),
+ INTC_VECT(IRL_C, 0x380),
+ INTC_VECT(IRL_D, 0x3a0),
+ INTC_VECT(IRL_E, 0x3c0),
+};
+
+static struct intc_group groups_irl[] = {
+ INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6,
+ IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E)
+};
+
+
static struct intc_vect vectors[] = {
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
@@ -717,5 +760,15 @@
NULL, 0);
}
+ sh_intc_register_sources(&s->intc,
+ _INTC_ARRAY(vectors_irl),
+ _INTC_ARRAY(groups_irl));
return s;
}
+
+qemu_irq sh7750_irl(SH7750State *s)
+{
+ sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
+ return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
+ 1)[0];
+}
Index: hw/ide.c
===================================================================
--- hw/ide.c (revision 5646)
+++ hw/ide.c (working copy)
@@ -3486,6 +3486,104 @@
}
/***********************************************************/
+/* MMIO based ide port
+ * This emulates IDE device connected directly to the CPU bus
+ * without dedicated ide controller, which is often seen on
+ * embedded boards.
+ */
+
+typedef struct {
+ void *dev;
+ int shift;
+} MMIOState;
+
+static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ return ide_ioport_read(ide, addr);
+ else
+ return ide_data_readw(ide, 0);
+}
+
+static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*) opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ ide_ioport_write(ide, addr, val);
+ else
+ ide_data_writew(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_reads[] = {
+ mmio_ide_read,
+ mmio_ide_read,
+ mmio_ide_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_writes[] = {
+ mmio_ide_write,
+ mmio_ide_write,
+ mmio_ide_write,
+};
+
+static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s = (MMIOState*) opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ return ide_status_read(ide, 0);
+}
+
+static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ ide_cmd_write(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_status[] = {
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_cmd[] = {
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+};
+
+void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1)
+{
+ MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+ IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+ int mem1, mem2;
+
+ ide_init2(ide, hd0, hd1, irq);
+
+ s->dev = ide;
+ s->shift = shift;
+
+ mem1 = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+ mem2 = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+ cpu_register_physical_memory(membase, 16<<shift, mem1);
+ cpu_register_physical_memory(membase2, 2<<shift, mem2);
+}
+/***************************************************************************/
+
+
+
+
+
+/***********************************************************/
/* CF-ATA Microdrive */
#define METADATA_SIZE 0x20
Index: hw/sh_intc.c
===================================================================
--- hw/sh_intc.c (revision 5646)
+++ hw/sh_intc.c (working copy)
@@ -451,3 +451,21 @@
return 0;
}
+
+/* Assert level <n> IRL interrupt
+ 0:deassert, 1:lowest priority... 15:highest priority */
+void sh_intc_set_irl(void *opaque, int n, int level)
+{
+ struct intc_source *s = opaque;
+ int i, irl = level ^ 15;
+ for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) {
+ if (i == irl)
+ sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1);
+ else
+ if (s->asserted)
+ sh_intc_toggle_source(s, 0, -1);
+ }
+}
+
+
+
Index: hw/sh_intc.h
===================================================================
--- hw/sh_intc.h (revision 5646)
+++ hw/sh_intc.h (working copy)
@@ -72,4 +72,6 @@
struct intc_prio_reg *prio_regs,
int nr_prio_regs);
+void sh_intc_set_irl(void *opaque, int n, int level);
+
#endif /* __SH_INTC_H__ */
--
Kristoffer Ericson <kristoffer.ericson@gmail.com>
[-- Attachment #1.2: big-sh4-svn-patch --]
[-- Type: application/octet-stream, Size: 15368 bytes --]
Index: target-sh4/helper.c
===================================================================
--- target-sh4/helper.c (revision 5646)
+++ target-sh4/helper.c (working copy)
@@ -359,14 +359,13 @@
int *prot, target_ulong address,
int rw, int access_type)
{
- int use_asid, is_code, n;
+ int use_asid, n;
tlb_t *matching = NULL;
use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
- is_code = env->pc == address; /* Hack */
/* Use a hack to find if this is an instruction or data access */
- if (env->pc == address && !(rw & PAGE_WRITE)) {
+ if (rw == 2) {
n = find_itlb_entry(env, address, use_asid, 1);
if (n >= 0) {
matching = &env->itlb[n];
@@ -382,13 +381,13 @@
switch ((matching->pr << 1) | ((env->sr & SR_MD) ? 1 : 0)) {
case 0: /* 000 */
case 2: /* 010 */
- n = (rw & PAGE_WRITE) ? MMU_DTLB_VIOLATION_WRITE :
+ n = (rw == 1) ? MMU_DTLB_VIOLATION_WRITE :
MMU_DTLB_VIOLATION_READ;
break;
case 1: /* 001 */
case 4: /* 100 */
case 5: /* 101 */
- if (rw & PAGE_WRITE)
+ if (rw == 1)
n = MMU_DTLB_VIOLATION_WRITE;
else
*prot = PAGE_READ;
@@ -396,11 +395,11 @@
case 3: /* 011 */
case 6: /* 110 */
case 7: /* 111 */
- *prot = rw & (PAGE_READ | PAGE_WRITE);
+ *prot = (rw == 1) ? PAGE_WRITE : PAGE_READ;
break;
}
} else if (n == MMU_DTLB_MISS) {
- n = (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
+ n = (rw == 1) ? MMU_DTLB_MISS_WRITE :
MMU_DTLB_MISS_READ;
}
}
@@ -426,8 +425,12 @@
&& (address < 0xe0000000 || address > 0xe4000000)) {
/* Unauthorized access in user mode (only store queues are available) */
fprintf(stderr, "Unauthorized access\n");
- return (rw & PAGE_WRITE) ? MMU_DTLB_MISS_WRITE :
- MMU_DTLB_MISS_READ;
+ if (rw == 0)
+ return MMU_DTLB_MISS_READ;
+ else if (rw == 1)
+ return MMU_DTLB_MISS_WRITE;
+ else
+ return MMU_ITLB_MISS;
}
if (address >= 0x80000000 && address < 0xc0000000) {
/* Mask upper 3 bits for P1 and P2 areas */
@@ -465,27 +468,6 @@
target_ulong physical, page_offset, page_size;
int prot, ret, access_type;
- switch (rw) {
- case 0:
- rw = PAGE_READ;
- break;
- case 1:
- rw = PAGE_WRITE;
- break;
- case 2: /* READ_ACCESS_TYPE == 2 defined in softmmu_template.h */
- rw = PAGE_READ;
- break;
- default:
- /* fatal error */
- assert(0);
- }
-
- /* XXXXX */
-#if 0
- fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
- __func__, env->pc, address, rw, mmu_idx, is_softmmu);
-#endif
-
access_type = ACCESS_INT;
ret =
get_physical_address(env, &physical, &prot, address, rw,
@@ -537,7 +519,7 @@
target_ulong physical;
int prot;
- get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
+ get_physical_address(env, &physical, &prot, addr, 0, 0);
return physical;
}
Index: Makefile.target
===================================================================
--- Makefile.target (revision 5646)
+++ Makefile.target (working copy)
@@ -738,6 +738,7 @@
ifeq ($(TARGET_BASE_ARCH), sh4)
OBJS+= shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
OBJS+= sh_timer.o ptimer.o sh_serial.o sh_intc.o sm501.o serial.o
+OBJS+= ide.o sh_pci.o
endif
ifeq ($(TARGET_BASE_ARCH), m68k)
OBJS+= an5206.o mcf5206.o ptimer.o mcf_uart.o mcf_intc.o mcf5208.o mcf_fec.o
Index: hw/r2d.c
===================================================================
--- hw/r2d.c (revision 5646)
+++ hw/r2d.c (working copy)
@@ -28,19 +28,24 @@
#include "devices.h"
#include "sysemu.h"
#include "boards.h"
+#include "pci.h"
+#include "net.h"
+#include "sh7750_regs.h"
#define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
#define SDRAM_SIZE 0x04000000
#define SM501_VRAM_SIZE 0x800000
+#define PA_IRLMSK 0x00
#define PA_POWOFF 0x30
#define PA_VERREG 0x32
#define PA_OUTPORT 0x36
typedef struct {
target_phys_addr_t base;
-
+ /*register */
+ uint16_t irlmsk;
uint16_t bcr;
uint16_t irlmon;
uint16_t cfctl;
@@ -62,8 +67,54 @@
uint16_t inport;
uint16_t outport;
uint16_t bverreg;
+
+ /* output_pin */
+ qemu_irq irl;
+
} r2d_fpga_t;
+enum r2d_fgpa_irq {
+ PCI_INTD, CF_IDE, CF_CD, PCI_INTC, SM501, KEY, RTC_A, RTC_T,
+ SDCARD, PCI_INTA, PCI_INTB, EXT, TP,
+ NR_IRQS
+};
+
+static const struct { short irl; uint16_t msk; } irqtab[NR_IRQS] = {
+ [CF_IDE] = { 1, 1<<9 },
+ [CF_CD] = { 2, 1<<8 },
+ [PCI_INTA] = { 9, 1<<14 },
+ [PCI_INTB] = {10, 1<<13 },
+ [PCI_INTC] = { 3, 1<<12 },
+ [PCI_INTD] = { 0, 1<<11 },
+ [SM501] = { 4, 1<<10 },
+ [KEY] = { 5, 1<<6 },
+ [RTC_A] = { 6, 1<<5 },
+ [RTC_T] = { 7, 1<<4 },
+ [SDCARD] = { 8, 1<<7 },
+ [EXT] = {11, 1<<0 },
+ [TP] = {12, 1<<15 },
+};
+
+static void update_irl(r2d_fpga_t *fpga)
+{
+ int i, irl = 15;
+ for (i = 0; i < NR_IRQS; i++)
+ if (fpga->irlmon & fpga->irlmsk & irqtab[i].msk)
+ if (irqtab[i].irl < irl)
+ irl = irqtab[i].irl;
+ qemu_set_irq(fpga->irl, irl ^ 15);
+}
+
+static void r2d_fpga_irq_set(void *opaque, int n, int level)
+{
+ r2d_fpga_t *fpga = opaque;
+ if (level)
+ fpga->irlmon |= irqtab[n].msk;
+ else
+ fpga->irlmon &= ~irqtab[n].msk;
+ update_irl(fpga);
+}
+
static uint32_t r2d_fpga_read(void *opaque, target_phys_addr_t addr)
{
r2d_fpga_t *s = opaque;
@@ -71,6 +122,8 @@
addr -= s->base;
switch (addr) {
+ case PA_IRLMSK:
+ return s->irlmsk;
case PA_OUTPORT:
return s->outport;
case PA_POWOFF:
@@ -90,6 +143,10 @@
addr -= s->base;
switch (addr) {
+ case PA_IRLMSK:
+ s->irlmsk = value;
+ update_irl(s);
+ break;
case PA_OUTPORT:
s->outport = value;
break;
@@ -114,21 +171,35 @@
NULL,
};
-static void r2d_fpga_init(target_phys_addr_t base)
+static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
{
int iomemtype;
r2d_fpga_t *s;
s = qemu_mallocz(sizeof(r2d_fpga_t));
if (!s)
- return;
+ return NULL;
+ s->irl = irl;
+
s->base = base;
iomemtype = cpu_register_io_memory(0, r2d_fpga_readfn,
r2d_fpga_writefn, s);
cpu_register_physical_memory(base, 0x40, iomemtype);
+ return qemu_allocate_irqs(r2d_fpga_irq_set, s, NR_IRQS);
}
+static void r2d_pci_set_irq(qemu_irq *p, int n, int l)
+{
+ qemu_set_irq(p[n], l);
+}
+
+static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
+{
+ const int intx[] = { PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD };
+ return intx[d->devfn>>3];
+}
+
static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
const char *boot_device, DisplayState * ds,
const char *kernel_filename, const char *kernel_cmdline,
@@ -136,6 +207,10 @@
{
CPUState *env;
struct SH7750State *s;
+ qemu_irq *irq;
+ PCIBus *pci;
+ int i;
+
ram_addr_t sdram_addr, sm501_vga_ram_addr;
if (!cpu_model)
@@ -151,14 +226,24 @@
sdram_addr = qemu_ram_alloc(SDRAM_SIZE);
cpu_register_physical_memory(SDRAM_BASE, SDRAM_SIZE, sdram_addr);
/* Register peripherals */
- r2d_fpga_init(0x04000000);
+ irq = r2d_fpga_init(0x04000000, sh7750_irl(s));
+ pci = sh_pci_register_bus(r2d_pci_set_irq, r2d_pci_map_irq, irq, 0, 4);
s = sh7750_init(env);
sm501_vga_ram_addr = qemu_ram_alloc(SM501_VRAM_SIZE);
sm501_init(ds, 0x10000000, sm501_vga_ram_addr, SM501_VRAM_SIZE,
serial_hds[2]);
+
+ mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
+ drives_table[drive_get_index(IF_IDE, 0, 0)].bdrv, NULL);
+
/* Todo: register on board registers */
{
int kernel_size;
+ /* initialization which should be done by firmware */
+ uint32_t bcr1 = 1<<3; // cs3 SDRAM
+ uint16_t bcr2 = 3<<(3*2); // cs3 32bit
+ cpu_physical_memory_write(SH7750_BCR1_A7, &bcr1, 4);
+ cpu_physical_memory_write(SH7750_BCR2_A7, &bcr2, 2);
kernel_size = load_image(kernel_filename, phys_ram_base);
Index: hw/sh.h
===================================================================
--- hw/sh.h (revision 5646)
+++ hw/sh.h (working copy)
@@ -42,7 +42,14 @@
struct intc_source *tei_source,
struct intc_source *bri_source);
+/* sh7750.c */
+qemu_irq sh7750_irl(struct SH7750State *s);
+
/* tc58128.c */
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
+/* ide.c */
+void mmio_ide_init(target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1);
#endif
Index: hw/sh7750.c
===================================================================
--- hw/sh7750.c (revision 5646)
+++ hw/sh7750.c (working copy)
@@ -41,6 +41,8 @@
/* Peripheral frequency in Hz */
uint32_t periph_freq;
/* SDRAM controller */
+ uint32_t bcr1;
+ uint32_t bcr2;
uint16_t rfcr;
/* IO ports */
uint16_t gpioic;
@@ -208,6 +210,8 @@
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR2_A7:
+ return s->bcr2;
case SH7750_FRQCR_A7:
return 0;
case SH7750_RFCR_A7:
@@ -231,6 +235,15 @@
SH7750State *s = opaque;
switch (addr) {
+ case SH7750_BCR1_A7:
+ return s->bcr1;
+ case SH7750_BCR4_A7:
+ case SH7750_WCR1_A7:
+ case SH7750_WCR2_A7:
+ case SH7750_WCR3_A7:
+ case SH7750_MCR_A7:
+ ignore_access("long read", addr);
+ return 0;
case SH7750_MMUCR_A7:
return s->cpu->mmucr;
case SH7750_PTEH_A7:
@@ -285,6 +298,8 @@
switch (addr) {
/* SDRAM controller */
case SH7750_BCR2_A7:
+ s->bcr2 = mem_value;
+ return;
case SH7750_BCR3_A7:
case SH7750_RTCOR_A7:
case SH7750_RTCNT_A7:
@@ -331,6 +346,8 @@
switch (addr) {
/* SDRAM controller */
case SH7750_BCR1_A7:
+ s->bcr1 = mem_value;
+ return;
case SH7750_BCR4_A7:
case SH7750_WCR1_A7:
case SH7750_WCR2_A7:
@@ -412,6 +429,8 @@
UNUSED = 0,
/* interrupt sources */
+ IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7,
+ IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E,
IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
HUDI, GPIOI,
DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
@@ -428,10 +447,34 @@
/* interrupt groups */
DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
-
+ IRL,
NR_SOURCES,
};
+static struct intc_vect vectors_irl[] = {
+ INTC_VECT(IRL_0, 0x200),
+ INTC_VECT(IRL_1, 0x220),
+ INTC_VECT(IRL_2, 0x240),
+ INTC_VECT(IRL_3, 0x260),
+ INTC_VECT(IRL_4, 0x280),
+ INTC_VECT(IRL_5, 0x2a0),
+ INTC_VECT(IRL_6, 0x2c0),
+ INTC_VECT(IRL_7, 0x2e0),
+ INTC_VECT(IRL_8, 0x300),
+ INTC_VECT(IRL_9, 0x320),
+ INTC_VECT(IRL_A, 0x340),
+ INTC_VECT(IRL_B, 0x360),
+ INTC_VECT(IRL_C, 0x380),
+ INTC_VECT(IRL_D, 0x3a0),
+ INTC_VECT(IRL_E, 0x3c0),
+};
+
+static struct intc_group groups_irl[] = {
+ INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6,
+ IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E)
+};
+
+
static struct intc_vect vectors[] = {
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
@@ -717,5 +760,15 @@
NULL, 0);
}
+ sh_intc_register_sources(&s->intc,
+ _INTC_ARRAY(vectors_irl),
+ _INTC_ARRAY(groups_irl));
return s;
}
+
+qemu_irq sh7750_irl(SH7750State *s)
+{
+ sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */
+ return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL),
+ 1)[0];
+}
Index: hw/ide.c
===================================================================
--- hw/ide.c (revision 5646)
+++ hw/ide.c (working copy)
@@ -3486,6 +3486,104 @@
}
/***********************************************************/
+/* MMIO based ide port
+ * This emulates IDE device connected directly to the CPU bus
+ * without dedicated ide controller, which is often seen on
+ * embedded boards.
+ */
+
+typedef struct {
+ void *dev;
+ int shift;
+} MMIOState;
+
+static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ return ide_ioport_read(ide, addr);
+ else
+ return ide_data_readw(ide, 0);
+}
+
+static void mmio_ide_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*) opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ addr >>= s->shift;
+ if (addr & 7)
+ ide_ioport_write(ide, addr, val);
+ else
+ ide_data_writew(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_reads[] = {
+ mmio_ide_read,
+ mmio_ide_read,
+ mmio_ide_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_writes[] = {
+ mmio_ide_write,
+ mmio_ide_write,
+ mmio_ide_write,
+};
+
+static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr)
+{
+ MMIOState *s = (MMIOState*) opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ return ide_status_read(ide, 0);
+}
+
+static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr,
+ uint32_t val)
+{
+ MMIOState *s = (MMIOState*)opaque;
+ IDEState *ide = (IDEState*)s->dev;
+ ide_cmd_write(ide, 0, val);
+}
+
+static CPUReadMemoryFunc *mmio_ide_status[] = {
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+ mmio_ide_status_read,
+};
+
+static CPUWriteMemoryFunc *mmio_ide_cmd[] = {
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+ mmio_ide_cmd_write,
+};
+
+void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
+ qemu_irq irq, int shift,
+ BlockDriverState *hd0, BlockDriverState *hd1)
+{
+ MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+ IDEState *ide = qemu_mallocz(sizeof(IDEState) * 2);
+ int mem1, mem2;
+
+ ide_init2(ide, hd0, hd1, irq);
+
+ s->dev = ide;
+ s->shift = shift;
+
+ mem1 = cpu_register_io_memory(0, mmio_ide_reads, mmio_ide_writes, s);
+ mem2 = cpu_register_io_memory(0, mmio_ide_status, mmio_ide_cmd, s);
+ cpu_register_physical_memory(membase, 16<<shift, mem1);
+ cpu_register_physical_memory(membase2, 2<<shift, mem2);
+}
+/***************************************************************************/
+
+
+
+
+
+/***********************************************************/
/* CF-ATA Microdrive */
#define METADATA_SIZE 0x20
Index: hw/sh_intc.c
===================================================================
--- hw/sh_intc.c (revision 5646)
+++ hw/sh_intc.c (working copy)
@@ -451,3 +451,21 @@
return 0;
}
+
+/* Assert level <n> IRL interrupt
+ 0:deassert, 1:lowest priority... 15:highest priority */
+void sh_intc_set_irl(void *opaque, int n, int level)
+{
+ struct intc_source *s = opaque;
+ int i, irl = level ^ 15;
+ for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) {
+ if (i == irl)
+ sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1);
+ else
+ if (s->asserted)
+ sh_intc_toggle_source(s, 0, -1);
+ }
+}
+
+
+
Index: hw/sh_intc.h
===================================================================
--- hw/sh_intc.h (revision 5646)
+++ hw/sh_intc.h (working copy)
@@ -72,4 +72,6 @@
struct intc_prio_reg *prio_regs,
int nr_prio_regs);
+void sh_intc_set_irl(void *opaque, int n, int level);
+
#endif /* __SH_INTC_H__ */
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.3: plain-file-sh_pci.c --]
[-- Type: text/x-csrc; name="plain-file-sh_pci.c", Size: 5952 bytes --]
/*
* SuperH on-chip PCIC emulation.
*
* Copyright (c) 2008 Takashi YOSHII
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
eal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "sh.h"
#include "pci.h"
typedef struct {
PCIBus *bus;
PCIDevice *dev;
uint32_t regbase;
uint32_t iopbase;
uint32_t membase;
uint32_t par;
uint32_t mbr;
uint32_t iobr;
} SHPCIC;
static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
{
SHPCIC *pcic = p;
addr -= pcic->regbase;
switch(addr) {
case 0 ... 0xff: *(uint32_t*)(pcic->dev->config + addr) = val;
case 0x1c0: pcic->par = val; break;
case 0x1c4: pcic->mbr = val; break;
case 0x1c8: pcic->iobr = val; break;
case 0x220: pci_data_write(pcic->bus, pcic->par, val, 4);
}
}
static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
{
SHPCIC *pcic = p;
addr -= pcic->regbase;
switch(addr) {
case 0 ... 0xff: return *(uint32_t*)(pcic->dev->config + addr);
case 0x1c0: return pcic->par;
case 0x220: return pci_data_read(pcic->bus, pcic->par, 4);
}
return 0;
}
static void sh_pci_data_write (SHPCIC *pcic, target_phys_addr_t addr,
uint32_t val, int size)
{
pci_data_write(pcic->bus, addr - pcic->membase + pcic->mbr, val, size);
}
static uint32_t sh_pci_mem_read (SHPCIC *pcic, target_phys_addr_t addr,
int size)
{
return pci_data_read(pcic->bus, addr - pcic->membase + pcic->mbr, size);
}
static void sh_pci_writeb (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 1);
}
static void sh_pci_writew (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 2);
}
static void sh_pci_writel (void *p, target_phys_addr_t addr, uint32_t val)
{
sh_pci_data_write(p, addr, val, 4);
}
static uint32_t sh_pci_readb (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 1);
}
static uint32_t sh_pci_readw (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 2);
}
static uint32_t sh_pci_readl (void *p, target_phys_addr_t addr)
{
return sh_pci_mem_read(p, addr, 4);
}
static int sh_pci_addr2port(SHPCIC *pcic, target_phys_addr_t addr)
{
return addr - pcic->iopbase + pcic->iobr;
}
static void sh_pci_outb (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outb(NULL, sh_pci_addr2port(p, addr), val);
}
static void sh_pci_outw (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outw(NULL, sh_pci_addr2port(p, addr), val);
}
static void sh_pci_outl (void *p, target_phys_addr_t addr, uint32_t val)
{
cpu_outl(NULL, sh_pci_addr2port(p, addr), val);
}
static uint32_t sh_pci_inb (void *p, target_phys_addr_t addr)
{
return cpu_inb(NULL, sh_pci_addr2port(p, addr));
}
static uint32_t sh_pci_inw (void *p, target_phys_addr_t addr)
{
return cpu_inw(NULL, sh_pci_addr2port(p, addr));
}
static uint32_t sh_pci_inl (void *p, target_phys_addr_t addr)
{
return cpu_inl(NULL, sh_pci_addr2port(p, addr));
}
typedef struct {
CPUReadMemoryFunc *r[3];
CPUWriteMemoryFunc *w[3];
} MemOp;
static MemOp sh_pci_reg = {
{ NULL, NULL, sh_pci_reg_read },
{ NULL, NULL, sh_pci_reg_write },
};
static MemOp sh_pci_mem = {
{ sh_pci_readb, sh_pci_readw, sh_pci_readl },
{ sh_pci_writeb, sh_pci_writew, sh_pci_writel },
};
static MemOp sh_pci_iop = {
{ sh_pci_inb, sh_pci_inw, sh_pci_inl },
{ sh_pci_outb, sh_pci_outw, sh_pci_outl },
};
PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq)
{
SHPCIC *p;
int mem, reg, iop;
p = qemu_mallocz(sizeof(SHPCIC));
p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq);
p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice),
-1, NULL, NULL);
p->regbase = 0x1e200000;
p->iopbase = 0x1e240000;
p->membase = 0xfd000000;
reg = cpu_register_io_memory(0, sh_pci_reg.r, sh_pci_reg.w, p);
mem = cpu_register_io_memory(0, sh_pci_mem.r, sh_pci_mem.w, p);
iop = cpu_register_io_memory(0, sh_pci_iop.r, sh_pci_iop.w, p);
cpu_register_physical_memory(p->regbase, 0x224, reg);
cpu_register_physical_memory(p->iopbase, 0x40000, iop);
cpu_register_physical_memory(p->membase, 0x1000000, mem);
p->dev->config[0x00] = 0x54; // HITACHI
p->dev->config[0x01] = 0x10; //
p->dev->config[0x02] = 0x0e; // SH7751R
p->dev->config[0x03] = 0x35; //
p->dev->config[0x04] = 0x80;
p->dev->config[0x05] = 0x00;
p->dev->config[0x06] = 0x90;
p->dev->config[0x07] = 0x02;
return p->bus;
}
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Concerning Qemu SH4
2008-11-08 0:01 Concerning Qemu SH4 Kristoffer Ericson
2008-11-08 15:28 ` takasi-y
2008-11-08 19:37 ` Kristoffer Ericson
@ 2008-11-08 19:42 ` Kristoffer Ericson
2 siblings, 0 replies; 4+ messages in thread
From: Kristoffer Ericson @ 2008-11-08 19:42 UTC (permalink / raw)
To: linux-sh
[-- Attachment #1: Type: text/plain, Size: 1665 bytes --]
Still getting segmentation fault, so I'm missing something. Either I've rewritten
the patch incorrectly or it's been broken upstreams.
On Sun, 9 Nov 2008 00:28:35 +0900 (JST)
takasi-y@ops.dti.ne.jp wrote:
> Hi,
>
> > Oki, gotten it to work now. Whats left is putting some sort
> > of harddrive file there. I've created an loop file but
> > can't seem to get it going.
> Have you applied all patches on ML?
> Otherwise it doesn't support hard disk.
> QEMU repository is being maintained very slowly.
> There always many patches left on ML waiting for being merged.
>
> Now, following patches are pending.
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg00970.html
> This must be applied. Otherwise it will be crashed frequently.
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01246.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01247.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-10/msg01248.html
> These three are needed use to use HDD.
> http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00118.html
> http://lists.gnu.org/archive/html/qemu-devel/2008-11/msg00119.html
> These two are needed to use network.
>
> Some of them can't be applied cleanly, because other patch has been
> applied after I posted them. Please edit them manually.
>
> > I'm also missing something with the initrd as it
> > constantly claims that the initrd expands beyond
> > the memory boundry.
> Current code doesn't support --initrd nor --append.
> Only --kernel works. Use initramfs and initial command line.
>
> /yoshii
--
Kristoffer Ericson <kristoffer.ericson@gmail.com>
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-11-08 19:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-08 0:01 Concerning Qemu SH4 Kristoffer Ericson
2008-11-08 15:28 ` takasi-y
2008-11-08 19:37 ` Kristoffer Ericson
2008-11-08 19:42 ` Kristoffer Ericson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox