Revision 12a71a02
b/hw/fdc.c | ||
---|---|---|
477 | 477 |
/* HW */ |
478 | 478 |
qemu_irq irq; |
479 | 479 |
int dma_chann; |
480 |
target_phys_addr_t io_base; |
|
481 | 480 |
/* Controller state */ |
482 | 481 |
QEMUTimer *result_timer; |
483 | 482 |
uint8_t sra; |
... | ... | |
512 | 511 |
/* Floppy drives */ |
513 | 512 |
fdrive_t drives[MAX_FD]; |
514 | 513 |
int reset_sensei; |
515 |
uint32_t strict_io; |
|
516 |
uint32_t mem_mapped; |
|
517 | 514 |
}; |
518 | 515 |
|
519 | 516 |
static uint32_t fdctrl_read (void *opaque, uint32_t reg) |
... | ... | |
1855 | 1852 |
} |
1856 | 1853 |
|
1857 | 1854 |
/* Init functions */ |
1858 |
static void fdctrl_init_common (fdctrl_t *fdctrl, int dma_chann, |
|
1859 |
target_phys_addr_t io_base, |
|
1860 |
BlockDriverState **fds) |
|
1855 |
static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds) |
|
1861 | 1856 |
{ |
1862 |
int i, j; |
|
1863 |
|
|
1864 |
/* Fill 'command_to_handler' lookup table */ |
|
1865 |
for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) { |
|
1866 |
for (j = 0; j < sizeof(command_to_handler); j++) { |
|
1867 |
if ((j & handlers[i].mask) == handlers[i].value) |
|
1868 |
command_to_handler[j] = i; |
|
1869 |
} |
|
1870 |
} |
|
1857 |
unsigned int i; |
|
1871 | 1858 |
|
1872 |
FLOPPY_DPRINTF("init controller\n"); |
|
1873 |
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); |
|
1874 |
fdctrl->result_timer = qemu_new_timer(vm_clock, |
|
1875 |
fdctrl_result_timer, fdctrl); |
|
1876 |
|
|
1877 |
fdctrl->version = 0x90; /* Intel 82078 controller */ |
|
1878 |
fdctrl->dma_chann = dma_chann; |
|
1879 |
fdctrl->io_base = io_base; |
|
1880 |
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ |
|
1881 |
if (fdctrl->dma_chann != -1) { |
|
1882 |
DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); |
|
1883 |
} |
|
1884 | 1859 |
for (i = 0; i < MAX_FD; i++) { |
1885 | 1860 |
fd_init(&fdctrl->drives[i], fds[i]); |
1886 |
} |
|
1887 |
fdctrl_external_reset(fdctrl); |
|
1888 |
register_savevm("fdc", io_base, 2, fdc_save, fdc_load, fdctrl); |
|
1889 |
qemu_register_reset(fdctrl_external_reset, fdctrl); |
|
1890 |
for (i = 0; i < MAX_FD; i++) { |
|
1891 | 1861 |
fd_revalidate(&fdctrl->drives[i]); |
1892 | 1862 |
} |
1893 | 1863 |
} |
... | ... | |
1901 | 1871 |
fdctrl_t *fdctrl; |
1902 | 1872 |
|
1903 | 1873 |
dev = qdev_create(NULL, "fdc"); |
1904 |
qdev_prop_set_uint32(dev, "strict_io", 0); |
|
1905 |
qdev_prop_set_uint32(dev, "mem_mapped", mem_mapped); |
|
1906 |
qdev_prop_set_uint32(dev, "sun4m", 0); |
|
1907 | 1874 |
qdev_init(dev); |
1908 | 1875 |
s = sysbus_from_qdev(dev); |
1909 | 1876 |
sysbus_connect_irq(s, 0, irq); |
... | ... | |
1920 | 1887 |
register_ioport_write((uint32_t)io_base + 0x07, 1, 1, |
1921 | 1888 |
&fdctrl_write_port, fdctrl); |
1922 | 1889 |
} |
1890 |
fdctrl->dma_chann = dma_chann; |
|
1891 |
DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); |
|
1923 | 1892 |
|
1924 |
fdctrl_init_common(fdctrl, dma_chann, io_base, fds);
|
|
1893 |
fdctrl_connect_drives(fdctrl, fds);
|
|
1925 | 1894 |
|
1926 | 1895 |
return fdctrl; |
1927 | 1896 |
} |
... | ... | |
1933 | 1902 |
SysBusDevice *s; |
1934 | 1903 |
fdctrl_t *fdctrl; |
1935 | 1904 |
|
1936 |
dev = qdev_create(NULL, "fdc"); |
|
1937 |
qdev_prop_set_uint32(dev, "strict_io", 1); |
|
1938 |
qdev_prop_set_uint32(dev, "mem_mapped", 1); |
|
1939 |
qdev_prop_set_uint32(dev, "sun4m", 1); |
|
1905 |
dev = qdev_create(NULL, "SUNW,fdtwo"); |
|
1940 | 1906 |
qdev_init(dev); |
1941 | 1907 |
s = sysbus_from_qdev(dev); |
1942 | 1908 |
sysbus_connect_irq(s, 0, irq); |
... | ... | |
1944 | 1910 |
*fdc_tc = qdev_get_gpio_in(dev, 0); |
1945 | 1911 |
|
1946 | 1912 |
fdctrl = FROM_SYSBUS(fdctrl_t, s); |
1947 |
fdctrl_init_common(fdctrl, -1, io_base, fds); |
|
1913 |
|
|
1914 |
fdctrl->dma_chann = -1; |
|
1915 |
|
|
1916 |
fdctrl_connect_drives(fdctrl, fds); |
|
1948 | 1917 |
|
1949 | 1918 |
return fdctrl; |
1950 | 1919 |
} |
1951 | 1920 |
|
1952 |
static void fdc_init1(SysBusDevice *dev) |
|
1921 |
static void fdctrl_init_common(SysBusDevice *dev, fdctrl_t *fdctrl, |
|
1922 |
int is_sun4m, int io) |
|
1953 | 1923 |
{ |
1954 |
fdctrl_t *s = FROM_SYSBUS(fdctrl_t, dev);
|
|
1955 |
int io;
|
|
1924 |
int i, j;
|
|
1925 |
static int command_tables_inited = 0;
|
|
1956 | 1926 |
|
1957 |
sysbus_init_irq(dev, &s->irq);
|
|
1927 |
sysbus_init_irq(dev, &fdctrl->irq);
|
|
1958 | 1928 |
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); |
1959 |
if (s->strict_io) { |
|
1960 |
io = cpu_register_io_memory(fdctrl_mem_read_strict, |
|
1961 |
fdctrl_mem_write_strict, s); |
|
1962 |
} else { |
|
1963 |
io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, s); |
|
1964 |
} |
|
1965 | 1929 |
sysbus_init_mmio(dev, 0x08, io); |
1930 |
|
|
1931 |
/* Fill 'command_to_handler' lookup table */ |
|
1932 |
if (!command_tables_inited) { |
|
1933 |
command_tables_inited = 1; |
|
1934 |
for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) { |
|
1935 |
for (j = 0; j < sizeof(command_to_handler); j++) { |
|
1936 |
if ((j & handlers[i].mask) == handlers[i].value) { |
|
1937 |
command_to_handler[j] = i; |
|
1938 |
} |
|
1939 |
} |
|
1940 |
} |
|
1941 |
} |
|
1942 |
|
|
1943 |
FLOPPY_DPRINTF("init controller\n"); |
|
1944 |
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); |
|
1945 |
fdctrl->result_timer = qemu_new_timer(vm_clock, |
|
1946 |
fdctrl_result_timer, fdctrl); |
|
1947 |
|
|
1948 |
fdctrl->version = 0x90; /* Intel 82078 controller */ |
|
1949 |
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ |
|
1950 |
fdctrl->sun4m = is_sun4m; |
|
1951 |
|
|
1952 |
fdctrl_external_reset(fdctrl); |
|
1953 |
register_savevm("fdc", -1, 2, fdc_save, fdc_load, fdctrl); |
|
1954 |
qemu_register_reset(fdctrl_external_reset, fdctrl); |
|
1966 | 1955 |
} |
1967 | 1956 |
|
1957 |
static void fdc_init1(SysBusDevice *dev) |
|
1958 |
{ |
|
1959 |
fdctrl_t *fdctrl = FROM_SYSBUS(fdctrl_t, dev); |
|
1960 |
int io; |
|
1961 |
|
|
1962 |
io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, fdctrl); |
|
1963 |
fdctrl_init_common(dev, fdctrl, 0, io); |
|
1964 |
} |
|
1965 |
|
|
1966 |
static void sun4m_fdc_init1(SysBusDevice *dev) |
|
1967 |
{ |
|
1968 |
fdctrl_t *fdctrl = FROM_SYSBUS(fdctrl_t, dev); |
|
1969 |
int io; |
|
1970 |
|
|
1971 |
io = cpu_register_io_memory(fdctrl_mem_read_strict, |
|
1972 |
fdctrl_mem_write_strict, fdctrl); |
|
1973 |
fdctrl_init_common(dev, fdctrl, 1, io); |
|
1974 |
} |
|
1968 | 1975 |
|
1969 | 1976 |
static SysBusDeviceInfo fdc_info = { |
1970 | 1977 |
.init = fdc_init1, |
1971 | 1978 |
.qdev.name = "fdc", |
1972 | 1979 |
.qdev.size = sizeof(fdctrl_t), |
1973 |
.qdev.props = (Property[]) { |
|
1974 |
{ |
|
1975 |
.name = "io_base", |
|
1976 |
.info = &qdev_prop_taddr, |
|
1977 |
.offset = offsetof(fdctrl_t, io_base), |
|
1978 |
}, |
|
1979 |
{ |
|
1980 |
.name = "strict_io", |
|
1981 |
.info = &qdev_prop_uint32, |
|
1982 |
.offset = offsetof(fdctrl_t, strict_io), |
|
1983 |
}, |
|
1984 |
{ |
|
1985 |
.name = "mem_mapped", |
|
1986 |
.info = &qdev_prop_uint32, |
|
1987 |
.offset = offsetof(fdctrl_t, mem_mapped), |
|
1988 |
}, |
|
1989 |
{ |
|
1990 |
.name = "sun4m", |
|
1991 |
.info = &qdev_prop_uint32, |
|
1992 |
.offset = offsetof(fdctrl_t, sun4m), |
|
1993 |
}, |
|
1994 |
{/* end of properties */} |
|
1995 |
} |
|
1980 |
}; |
|
1981 |
|
|
1982 |
static SysBusDeviceInfo sun4m_fdc_info = { |
|
1983 |
.init = sun4m_fdc_init1, |
|
1984 |
.qdev.name = "SUNW,fdtwo", |
|
1985 |
.qdev.size = sizeof(fdctrl_t), |
|
1996 | 1986 |
}; |
1997 | 1987 |
|
1998 | 1988 |
static void fdc_register_devices(void) |
1999 | 1989 |
{ |
2000 | 1990 |
sysbus_register_withprop(&fdc_info); |
1991 |
sysbus_register_withprop(&sun4m_fdc_info); |
|
2001 | 1992 |
} |
2002 | 1993 |
|
2003 | 1994 |
device_init(fdc_register_devices) |
Also available in: Unified diff