diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-06-21 16:47:42 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-06-21 16:47:42 +0000 |
commit | b0bda528c37d7a772343a5eee8772dc56c8470f7 (patch) | |
tree | a35f302f84e7bfbb5a4c7f5e0d1599ec355ae946 /hw | |
parent | 819e712bfe40f0706689a98f9968f842e3aaccd1 (diff) |
high page register support for PPC PREP
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@951 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r-- | hw/dma.c | 49 |
1 files changed, 42 insertions, 7 deletions
@@ -43,6 +43,7 @@ struct dma_regs { uint16_t base[2]; uint8_t mode; uint8_t page; + uint8_t pageh; uint8_t dack; uint8_t eop; DMA_transfer_handler transfer_handler; @@ -84,7 +85,6 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) int ichan; ichan = channels[nport & 7]; - if (-1 == ichan) { log ("invalid channel %#x %#x\n", nport, data); return; @@ -92,13 +92,25 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) d->regs[ichan].page = data; } -static uint32_t read_page (void *opaque, uint32_t nport) +static void write_pageh (void *opaque, uint32_t nport, uint32_t data) { struct dma_cont *d = opaque; int ichan; ichan = channels[nport & 7]; + if (-1 == ichan) { + log ("invalid channel %#x %#x\n", nport, data); + return; + } + d->regs[ichan].pageh = data; +} +static uint32_t read_page (void *opaque, uint32_t nport) +{ + struct dma_cont *d = opaque; + int ichan; + + ichan = channels[nport & 7]; if (-1 == ichan) { log ("invalid channel read %#x\n", nport); return 0; @@ -106,6 +118,19 @@ static uint32_t read_page (void *opaque, uint32_t nport) return d->regs[ichan].page; } +static uint32_t read_pageh (void *opaque, uint32_t nport) +{ + struct dma_cont *d = opaque; + int ichan; + + ichan = channels[nport & 7]; + if (-1 == ichan) { + log ("invalid channel read %#x\n", nport); + return 0; + } + return d->regs[ichan].pageh; +} + static inline void init_chan (struct dma_cont *d, int ichan) { struct dma_regs *r; @@ -306,7 +331,8 @@ static void channel_run (int ncont, int ichan) /* ai = r->mode & 16; */ /* dir = r->mode & 32 ? -1 : 1; */ - addr = (r->page << 16) | r->now[ADDR]; + /* NOTE: pageh is only used by PPC PREP */ + addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; n = r->transfer_handler (r->opaque, addr, (r->base[COUNT] << ncont) + (1 << ncont)); r->now[COUNT] = n; @@ -362,7 +388,8 @@ static void dma_reset(void *opaque) } /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ -static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) +static void dma_init2(struct dma_cont *d, int base, int dshift, + int page_base, int pageh_base) { const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 }; int i; @@ -377,6 +404,12 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) write_page, d); register_ioport_read (page_base + page_port_list[i], 1, 1, read_page, d); + if (pageh_base >= 0) { + register_ioport_write (pageh_base + page_port_list[i], 1, 1, + write_pageh, d); + register_ioport_read (pageh_base + page_port_list[i], 1, 1, + read_pageh, d); + } } for (i = 0; i < 8; i++) { register_ioport_write (base + ((i + 8) << dshift), 1, 1, @@ -388,8 +421,10 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) dma_reset(d); } -void DMA_init (void) +void DMA_init (int high_page_enable) { - dma_init2(&dma_controllers[0], 0x00, 0, 0x80); - dma_init2(&dma_controllers[1], 0xc0, 1, 0x88); + dma_init2(&dma_controllers[0], 0x00, 0, 0x80, + high_page_enable ? 0x480 : -1); + dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, + high_page_enable ? 0x488 : -1); } |