Commit b0bda528c37d7a772343a5eee8772dc56c8470f7

Authored by bellard
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,6 +43,7 @@ struct dma_regs {
43 uint16_t base[2]; 43 uint16_t base[2];
44 uint8_t mode; 44 uint8_t mode;
45 uint8_t page; 45 uint8_t page;
  46 + uint8_t pageh;
46 uint8_t dack; 47 uint8_t dack;
47 uint8_t eop; 48 uint8_t eop;
48 DMA_transfer_handler transfer_handler; 49 DMA_transfer_handler transfer_handler;
@@ -84,7 +85,6 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) @@ -84,7 +85,6 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data)
84 int ichan; 85 int ichan;
85 86
86 ichan = channels[nport & 7]; 87 ichan = channels[nport & 7];
87 -  
88 if (-1 == ichan) { 88 if (-1 == ichan) {
89 log ("invalid channel %#x %#x\n", nport, data); 89 log ("invalid channel %#x %#x\n", nport, data);
90 return; 90 return;
@@ -92,13 +92,25 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data) @@ -92,13 +92,25 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data)
92 d->regs[ichan].page = data; 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 struct dma_cont *d = opaque; 97 struct dma_cont *d = opaque;
98 int ichan; 98 int ichan;
99 99
100 ichan = channels[nport & 7]; 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 if (-1 == ichan) { 114 if (-1 == ichan) {
103 log ("invalid channel read %#x\n", nport); 115 log ("invalid channel read %#x\n", nport);
104 return 0; 116 return 0;
@@ -106,6 +118,19 @@ static uint32_t read_page (void *opaque, uint32_t nport) @@ -106,6 +118,19 @@ static uint32_t read_page (void *opaque, uint32_t nport)
106 return d->regs[ichan].page; 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 static inline void init_chan (struct dma_cont *d, int ichan) 134 static inline void init_chan (struct dma_cont *d, int ichan)
110 { 135 {
111 struct dma_regs *r; 136 struct dma_regs *r;
@@ -306,7 +331,8 @@ static void channel_run (int ncont, int ichan) @@ -306,7 +331,8 @@ static void channel_run (int ncont, int ichan)
306 /* ai = r->mode & 16; */ 331 /* ai = r->mode & 16; */
307 /* dir = r->mode & 32 ? -1 : 1; */ 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 n = r->transfer_handler (r->opaque, addr, 336 n = r->transfer_handler (r->opaque, addr,
311 (r->base[COUNT] << ncont) + (1 << ncont)); 337 (r->base[COUNT] << ncont) + (1 << ncont));
312 r->now[COUNT] = n; 338 r->now[COUNT] = n;
@@ -362,7 +388,8 @@ static void dma_reset(void *opaque) @@ -362,7 +388,8 @@ static void dma_reset(void *opaque)
362 } 388 }
363 389
364 /* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */ 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 const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 }; 394 const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
368 int i; 395 int i;
@@ -377,6 +404,12 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base) @@ -377,6 +404,12 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base)
377 write_page, d); 404 write_page, d);
378 register_ioport_read (page_base + page_port_list[i], 1, 1, 405 register_ioport_read (page_base + page_port_list[i], 1, 1,
379 read_page, d); 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 for (i = 0; i < 8; i++) { 414 for (i = 0; i < 8; i++) {
382 register_ioport_write (base + ((i + 8) << dshift), 1, 1, 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,8 +421,10 @@ static void dma_init2(struct dma_cont *d, int base, int dshift, int page_base)
388 dma_reset(d); 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 }