1 | /* |
2 | * SMC FDC37C669 Super I/O controller |
3 | * |
4 | * Copyright (c) 2018 Philippe Mathieu-Daudé |
5 | * |
6 | * This code is licensed under the GNU GPLv2 and later. |
7 | * See the COPYING file in the top-level directory. |
8 | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | */ |
10 | |
11 | #include "qemu/osdep.h" |
12 | #include "hw/isa/superio.h" |
13 | #include "qemu/module.h" |
14 | |
15 | /* UARTs (compatible with NS16450 or PC16550) */ |
16 | |
17 | static bool is_serial_enabled(ISASuperIODevice *sio, uint8_t index) |
18 | { |
19 | return index < 2; |
20 | } |
21 | |
22 | static uint16_t get_serial_iobase(ISASuperIODevice *sio, uint8_t index) |
23 | { |
24 | return index ? 0x2f8 : 0x3f8; |
25 | } |
26 | |
27 | static unsigned int get_serial_irq(ISASuperIODevice *sio, uint8_t index) |
28 | { |
29 | return index ? 3 : 4; |
30 | } |
31 | |
32 | /* Parallel port */ |
33 | |
34 | static bool is_parallel_enabled(ISASuperIODevice *sio, uint8_t index) |
35 | { |
36 | return index < 1; |
37 | } |
38 | |
39 | static uint16_t get_parallel_iobase(ISASuperIODevice *sio, uint8_t index) |
40 | { |
41 | return 0x378; |
42 | } |
43 | |
44 | static unsigned int get_parallel_irq(ISASuperIODevice *sio, uint8_t index) |
45 | { |
46 | return 7; |
47 | } |
48 | |
49 | static unsigned int get_parallel_dma(ISASuperIODevice *sio, uint8_t index) |
50 | { |
51 | return 3; |
52 | } |
53 | |
54 | /* Diskette controller (Software compatible with the Intel PC8477) */ |
55 | |
56 | static bool is_fdc_enabled(ISASuperIODevice *sio, uint8_t index) |
57 | { |
58 | return index < 1; |
59 | } |
60 | |
61 | static uint16_t get_fdc_iobase(ISASuperIODevice *sio, uint8_t index) |
62 | { |
63 | return 0x3f0; |
64 | } |
65 | |
66 | static unsigned int get_fdc_irq(ISASuperIODevice *sio, uint8_t index) |
67 | { |
68 | return 6; |
69 | } |
70 | |
71 | static unsigned int get_fdc_dma(ISASuperIODevice *sio, uint8_t index) |
72 | { |
73 | return 2; |
74 | } |
75 | |
76 | static void smc37c669_class_init(ObjectClass *klass, void *data) |
77 | { |
78 | ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); |
79 | |
80 | sc->parallel = (ISASuperIOFuncs){ |
81 | .count = 1, |
82 | .is_enabled = is_parallel_enabled, |
83 | .get_iobase = get_parallel_iobase, |
84 | .get_irq = get_parallel_irq, |
85 | .get_dma = get_parallel_dma, |
86 | }; |
87 | sc->serial = (ISASuperIOFuncs){ |
88 | .count = 2, |
89 | .is_enabled = is_serial_enabled, |
90 | .get_iobase = get_serial_iobase, |
91 | .get_irq = get_serial_irq, |
92 | }; |
93 | sc->floppy = (ISASuperIOFuncs){ |
94 | .count = 1, |
95 | .is_enabled = is_fdc_enabled, |
96 | .get_iobase = get_fdc_iobase, |
97 | .get_irq = get_fdc_irq, |
98 | .get_dma = get_fdc_dma, |
99 | }; |
100 | sc->ide.count = 0; |
101 | } |
102 | |
103 | static const TypeInfo smc37c669_type_info = { |
104 | .name = TYPE_SMC37C669_SUPERIO, |
105 | .parent = TYPE_ISA_SUPERIO, |
106 | .instance_size = sizeof(ISASuperIODevice), |
107 | .class_size = sizeof(ISASuperIOClass), |
108 | .class_init = smc37c669_class_init, |
109 | }; |
110 | |
111 | static void smc37c669_register_types(void) |
112 | { |
113 | type_register_static(&smc37c669_type_info); |
114 | } |
115 | |
116 | type_init(smc37c669_register_types) |
117 | |