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