Commit b0bda528c37d7a772343a5eee8772dc56c8470f7
1 parent
819e712b
high page register support for PPC PREP
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@951 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
42 additions
and
7 deletions
hw/dma.c
| ... | ... | @@ -43,6 +43,7 @@ struct dma_regs { |
| 43 | 43 | uint16_t base[2]; |
| 44 | 44 | uint8_t mode; |
| 45 | 45 | uint8_t page; |
| 46 | + uint8_t pageh; | |
| 46 | 47 | uint8_t dack; |
| 47 | 48 | uint8_t eop; |
| 48 | 49 | DMA_transfer_handler transfer_handler; |
| ... | ... | @@ -84,7 +85,6 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) |
| 84 | 85 | int ichan; |
| 85 | 86 | |
| 86 | 87 | ichan = channels[nport & 7]; |
| 87 | - | |
| 88 | 88 | if (-1 == ichan) { |
| 89 | 89 | log ("invalid channel %#x %#x\n", nport, data); |
| 90 | 90 | return; |
| ... | ... | @@ -92,13 +92,25 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) |
| 92 | 92 | d->regs[ichan].page = data; |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | -static uint32_t read_page (void *opaque, uint32_t nport) | |
| 95 | +static void write_pageh (void *opaque, uint32_t nport, uint32_t data) | |
| 96 | 96 | { |
| 97 | 97 | struct dma_cont *d = opaque; |
| 98 | 98 | int ichan; |
| 99 | 99 | |
| 100 | 100 | ichan = channels[nport & 7]; |
| 101 | + if (-1 == ichan) { | |
| 102 | + log ("invalid channel %#x %#x\n", nport, data); | |
| 103 | + return; | |
| 104 | + } | |
| 105 | + d->regs[ichan].pageh = data; | |
| 106 | +} | |
| 101 | 107 | |
| 108 | +static uint32_t read_page (void *opaque, uint32_t nport) | |
| 109 | +{ | |
| 110 | + struct dma_cont *d = opaque; | |
| 111 | + int ichan; | |
| 112 | + | |
| 113 | + ichan = channels[nport & 7]; | |
| 102 | 114 | if (-1 == ichan) { |
| 103 | 115 | log ("invalid channel read %#x\n", nport); |
| 104 | 116 | return 0; |
| ... | ... | @@ -106,6 +118,19 @@ static uint32_t read_page (void *opaque, uint32_t nport) |
| 106 | 118 | return d->regs[ichan].page; |
| 107 | 119 | } |
| 108 | 120 | |
| 121 | +static uint32_t read_pageh (void *opaque, uint32_t nport) | |
| 122 | +{ | |
| 123 | + struct dma_cont *d = opaque; | |
| 124 | + int ichan; | |
| 125 | + | |
| 126 | + ichan = channels[nport & 7]; | |
| 127 | + if (-1 == ichan) { | |
| 128 | + log ("invalid channel read %#x\n", nport); | |
| 129 | + return 0; | |
| 130 | + } | |
| 131 | + return d->regs[ichan].pageh; | |
| 132 | +} | |
| 133 | + | |
| 109 | 134 | static inline void init_chan (struct dma_cont *d, int ichan) |
| 110 | 135 | { |
| 111 | 136 | struct dma_regs *r; |
| ... | ... | @@ -306,7 +331,8 @@ static void channel_run (int ncont, int ichan) |
| 306 | 331 | /* ai = r->mode & 16; */ |
| 307 | 332 | /* dir = r->mode & 32 ? -1 : 1; */ |
| 308 | 333 | |
| 309 | - addr = (r->page << 16) | r->now[ADDR]; | |
| 334 | + /* NOTE: pageh is only used by PPC PREP */ | |
| 335 | + addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR]; | |
| 310 | 336 | n = r->transfer_handler (r->opaque, addr, |
| 311 | 337 | (r->base[COUNT] << ncont) + (1 << ncont)); |
| 312 | 338 | r->now[COUNT] = n; |
| ... | ... | @@ -362,7 +388,8 @@ static void dma_reset(void *opaque) |
| 362 | 388 | } |
| 363 | 389 | |
| 364 | 390 | /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ |
| 365 | -static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) | |
| 391 | +static void dma_init2(struct dma_cont *d, int base, int dshift, | |
| 392 | + int page_base, int pageh_base) | |
| 366 | 393 | { |
| 367 | 394 | const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 }; |
| 368 | 395 | int i; |
| ... | ... | @@ -377,6 +404,12 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) |
| 377 | 404 | write_page, d); |
| 378 | 405 | register_ioport_read (page_base + page_port_list[i], 1, 1, |
| 379 | 406 | read_page, d); |
| 407 | + if (pageh_base >= 0) { | |
| 408 | + register_ioport_write (pageh_base + page_port_list[i], 1, 1, | |
| 409 | + write_pageh, d); | |
| 410 | + register_ioport_read (pageh_base + page_port_list[i], 1, 1, | |
| 411 | + read_pageh, d); | |
| 412 | + } | |
| 380 | 413 | } |
| 381 | 414 | for (i = 0; i < 8; i++) { |
| 382 | 415 | 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) |
| 388 | 421 | dma_reset(d); |
| 389 | 422 | } |
| 390 | 423 | |
| 391 | -void DMA_init (void) | |
| 424 | +void DMA_init (int high_page_enable) | |
| 392 | 425 | { |
| 393 | - dma_init2(&dma_controllers[0], 0x00, 0, 0x80); | |
| 394 | - dma_init2(&dma_controllers[1], 0xc0, 1, 0x88); | |
| 426 | + dma_init2(&dma_controllers[0], 0x00, 0, 0x80, | |
| 427 | + high_page_enable ? 0x480 : -1); | |
| 428 | + dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, | |
| 429 | + high_page_enable ? 0x488 : -1); | |
| 395 | 430 | } | ... | ... |