21 |
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
22 |
* THE SOFTWARE.
|
23 |
23 |
*/
|
24 |
|
#include "hw.h"
|
|
24 |
|
25 |
25 |
#include "sun4m.h"
|
26 |
26 |
#include "console.h"
|
27 |
27 |
#include "pixel_ops.h"
|
|
28 |
#include "sysbus.h"
|
28 |
29 |
|
29 |
30 |
#define MAXX 1024
|
30 |
31 |
#define MAXY 768
|
... | ... | |
34 |
35 |
#define TCX_TEC_NREGS 0x1000
|
35 |
36 |
|
36 |
37 |
typedef struct TCXState {
|
|
38 |
SysBusDevice busdev;
|
37 |
39 |
target_phys_addr_t addr;
|
38 |
40 |
DisplayState *ds;
|
39 |
41 |
uint8_t *vram;
|
... | ... | |
500 |
502 |
void tcx_init(target_phys_addr_t addr, int vram_size, int width, int height,
|
501 |
503 |
int depth)
|
502 |
504 |
{
|
503 |
|
TCXState *s;
|
|
505 |
DeviceState *dev;
|
|
506 |
SysBusDevice *s;
|
|
507 |
|
|
508 |
dev = qdev_create(NULL, "SUNW,tcx");
|
|
509 |
qdev_set_prop_int(dev, "addr", addr);
|
|
510 |
qdev_set_prop_int(dev, "vram_size", vram_size);
|
|
511 |
qdev_set_prop_int(dev, "width", width);
|
|
512 |
qdev_set_prop_int(dev, "height", height);
|
|
513 |
qdev_set_prop_int(dev, "depth", depth);
|
|
514 |
qdev_init(dev);
|
|
515 |
s = sysbus_from_qdev(dev);
|
|
516 |
/* 8-bit plane */
|
|
517 |
sysbus_mmio_map(s, 0, addr + 0x00800000ULL);
|
|
518 |
/* DAC */
|
|
519 |
sysbus_mmio_map(s, 1, addr + 0x00200000ULL);
|
|
520 |
/* TEC (dummy) */
|
|
521 |
sysbus_mmio_map(s, 2, addr + 0x00700000ULL);
|
|
522 |
/* THC 24 bit: NetBSD writes here even with 8-bit display: dummy */
|
|
523 |
sysbus_mmio_map(s, 3, addr + 0x00301000ULL);
|
|
524 |
if (depth == 24) {
|
|
525 |
/* 24-bit plane */
|
|
526 |
sysbus_mmio_map(s, 4, addr + 0x02000000ULL);
|
|
527 |
/* Control plane */
|
|
528 |
sysbus_mmio_map(s, 5, addr + 0x0a000000ULL);
|
|
529 |
} else {
|
|
530 |
/* THC 8 bit (dummy) */
|
|
531 |
sysbus_mmio_map(s, 4, addr + 0x00300000ULL);
|
|
532 |
}
|
|
533 |
}
|
|
534 |
|
|
535 |
static void tcx_init1(SysBusDevice *dev)
|
|
536 |
{
|
|
537 |
TCXState *s = FROM_SYSBUS(TCXState, dev);
|
504 |
538 |
int io_memory, dummy_memory;
|
505 |
539 |
ram_addr_t vram_offset;
|
506 |
|
int size;
|
|
540 |
int size, vram_size;
|
507 |
541 |
uint8_t *vram_base;
|
508 |
542 |
|
|
543 |
vram_size = qdev_get_prop_int(&dev->qdev, "vram_size", -1);
|
|
544 |
|
509 |
545 |
vram_offset = qemu_ram_alloc(vram_size * (1 + 4 + 4));
|
510 |
546 |
vram_base = qemu_get_ram_ptr(vram_offset);
|
511 |
|
|
512 |
|
s = qemu_mallocz(sizeof(TCXState));
|
513 |
|
s->addr = addr;
|
|
547 |
s->addr = qdev_get_prop_int(&dev->qdev, "addr", -1);
|
514 |
548 |
s->vram_offset = vram_offset;
|
515 |
|
s->width = width;
|
516 |
|
s->height = height;
|
517 |
|
s->depth = depth;
|
|
549 |
s->width = qdev_get_prop_int(&dev->qdev, "width", -1);
|
|
550 |
s->height = qdev_get_prop_int(&dev->qdev, "height", -1);
|
|
551 |
s->depth = qdev_get_prop_int(&dev->qdev, "depth", -1);
|
518 |
552 |
|
519 |
|
// 8-bit plane
|
|
553 |
/* 8-bit plane */
|
520 |
554 |
s->vram = vram_base;
|
521 |
555 |
size = vram_size;
|
522 |
|
cpu_register_physical_memory(addr + 0x00800000ULL, size, vram_offset);
|
|
556 |
sysbus_init_mmio(dev, size, s->vram_offset);
|
523 |
557 |
vram_offset += size;
|
524 |
558 |
vram_base += size;
|
525 |
559 |
|
|
560 |
/* DAC */
|
526 |
561 |
io_memory = cpu_register_io_memory(tcx_dac_read, tcx_dac_write, s);
|
527 |
|
cpu_register_physical_memory(addr + 0x00200000ULL, TCX_DAC_NREGS,
|
528 |
|
io_memory);
|
|
562 |
sysbus_init_mmio(dev, TCX_DAC_NREGS, io_memory);
|
529 |
563 |
|
|
564 |
/* TEC (dummy) */
|
530 |
565 |
dummy_memory = cpu_register_io_memory(tcx_dummy_read, tcx_dummy_write,
|
531 |
566 |
s);
|
532 |
|
cpu_register_physical_memory(addr + 0x00700000ULL, TCX_TEC_NREGS,
|
533 |
|
dummy_memory);
|
534 |
|
if (depth == 24) {
|
535 |
|
// 24-bit plane
|
|
567 |
sysbus_init_mmio(dev, TCX_TEC_NREGS, dummy_memory);
|
|
568 |
/* THC: NetBSD writes here even with 8-bit display: dummy */
|
|
569 |
sysbus_init_mmio(dev, TCX_THC_NREGS_24, dummy_memory);
|
|
570 |
|
|
571 |
if (s->depth == 24) {
|
|
572 |
/* 24-bit plane */
|
536 |
573 |
size = vram_size * 4;
|
537 |
574 |
s->vram24 = (uint32_t *)vram_base;
|
538 |
575 |
s->vram24_offset = vram_offset;
|
539 |
|
cpu_register_physical_memory(addr + 0x02000000ULL, size, vram_offset);
|
|
576 |
sysbus_init_mmio(dev, size, vram_offset);
|
540 |
577 |
vram_offset += size;
|
541 |
578 |
vram_base += size;
|
542 |
579 |
|
543 |
|
// Control plane
|
|
580 |
/* Control plane */
|
544 |
581 |
size = vram_size * 4;
|
545 |
582 |
s->cplane = (uint32_t *)vram_base;
|
546 |
583 |
s->cplane_offset = vram_offset;
|
547 |
|
cpu_register_physical_memory(addr + 0x0a000000ULL, size, vram_offset);
|
|
584 |
sysbus_init_mmio(dev, size, vram_offset);
|
|
585 |
|
548 |
586 |
s->ds = graphic_console_init(tcx24_update_display,
|
549 |
587 |
tcx24_invalidate_display,
|
550 |
588 |
tcx24_screen_dump, NULL, s);
|
551 |
589 |
} else {
|
552 |
|
cpu_register_physical_memory(addr + 0x00300000ULL, TCX_THC_NREGS_8,
|
553 |
|
dummy_memory);
|
|
590 |
/* THC 8 bit (dummy) */
|
|
591 |
sysbus_init_mmio(dev, TCX_THC_NREGS_8, dummy_memory);
|
|
592 |
|
554 |
593 |
s->ds = graphic_console_init(tcx_update_display,
|
555 |
594 |
tcx_invalidate_display,
|
556 |
595 |
tcx_screen_dump, NULL, s);
|
557 |
596 |
}
|
558 |
|
// NetBSD writes here even with 8-bit display
|
559 |
|
cpu_register_physical_memory(addr + 0x00301000ULL, TCX_THC_NREGS_24,
|
560 |
|
dummy_memory);
|
561 |
597 |
|
562 |
|
register_savevm("tcx", addr, 4, tcx_save, tcx_load, s);
|
|
598 |
register_savevm("tcx", -1, 4, tcx_save, tcx_load, s);
|
563 |
599 |
qemu_register_reset(tcx_reset, s);
|
564 |
600 |
tcx_reset(s);
|
565 |
|
qemu_console_resize(s->ds, width, height);
|
|
601 |
qemu_console_resize(s->ds, s->width, s->height);
|
566 |
602 |
}
|
567 |
603 |
|
568 |
604 |
static void tcx_screen_dump(void *opaque, const char *filename)
|
... | ... | |
627 |
663 |
fclose(f);
|
628 |
664 |
return;
|
629 |
665 |
}
|
|
666 |
|
|
667 |
static void tcx_register_devices(void)
|
|
668 |
{
|
|
669 |
sysbus_register_dev("SUNW,tcx", sizeof(TCXState), tcx_init1);
|
|
670 |
}
|
|
671 |
|
|
672 |
device_init(tcx_register_devices)
|