Revision f64ab228 hw/fdc.c
b/hw/fdc.c | ||
---|---|---|
26 | 26 |
* The controller is used in Sun4m systems in a slightly different |
27 | 27 |
* way. There are changes in DOR register and DMA is not available. |
28 | 28 |
*/ |
29 |
|
|
29 | 30 |
#include "hw.h" |
30 | 31 |
#include "fdc.h" |
31 | 32 |
#include "block.h" |
32 | 33 |
#include "qemu-timer.h" |
33 | 34 |
#include "isa.h" |
35 |
#include "sysbus.h" |
|
34 | 36 |
|
35 | 37 |
/********************************************************/ |
36 | 38 |
/* debug Floppy devices */ |
... | ... | |
468 | 470 |
#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT) |
469 | 471 |
|
470 | 472 |
struct fdctrl_t { |
473 |
SysBusDevice busdev; |
|
471 | 474 |
/* Controller's identification */ |
472 | 475 |
uint8_t version; |
473 | 476 |
/* HW */ |
... | ... | |
1849 | 1852 |
} |
1850 | 1853 |
|
1851 | 1854 |
/* Init functions */ |
1852 |
static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann,
|
|
1853 |
target_phys_addr_t io_base,
|
|
1854 |
BlockDriverState **fds)
|
|
1855 |
static void fdctrl_init_common (fdctrl_t *fdctrl, int dma_chann,
|
|
1856 |
target_phys_addr_t io_base, |
|
1857 |
BlockDriverState **fds) |
|
1855 | 1858 |
{ |
1856 |
fdctrl_t *fdctrl; |
|
1857 | 1859 |
int i, j; |
1858 | 1860 |
|
1859 | 1861 |
/* Fill 'command_to_handler' lookup table */ |
... | ... | |
1865 | 1867 |
} |
1866 | 1868 |
|
1867 | 1869 |
FLOPPY_DPRINTF("init controller\n"); |
1868 |
fdctrl = qemu_mallocz(sizeof(fdctrl_t)); |
|
1869 | 1870 |
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); |
1870 | 1871 |
fdctrl->result_timer = qemu_new_timer(vm_clock, |
1871 | 1872 |
fdctrl_result_timer, fdctrl); |
1872 | 1873 |
|
1873 | 1874 |
fdctrl->version = 0x90; /* Intel 82078 controller */ |
1874 |
fdctrl->irq = irq; |
|
1875 | 1875 |
fdctrl->dma_chann = dma_chann; |
1876 | 1876 |
fdctrl->io_base = io_base; |
1877 | 1877 |
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ |
... | ... | |
1887 | 1887 |
for (i = 0; i < MAX_FD; i++) { |
1888 | 1888 |
fd_revalidate(&fdctrl->drives[i]); |
1889 | 1889 |
} |
1890 |
|
|
1891 |
return fdctrl; |
|
1892 | 1890 |
} |
1893 | 1891 |
|
1894 | 1892 |
fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped, |
1895 | 1893 |
target_phys_addr_t io_base, |
1896 | 1894 |
BlockDriverState **fds) |
1897 | 1895 |
{ |
1896 |
DeviceState *dev; |
|
1897 |
SysBusDevice *s; |
|
1898 | 1898 |
fdctrl_t *fdctrl; |
1899 |
int io_mem; |
|
1900 |
|
|
1901 |
fdctrl = fdctrl_init_common(irq, dma_chann, io_base, fds); |
|
1902 | 1899 |
|
1903 |
fdctrl->sun4m = 0; |
|
1900 |
dev = qdev_create(NULL, "fdc"); |
|
1901 |
qdev_set_prop_int(dev, "strict_io", 0); |
|
1902 |
qdev_set_prop_int(dev, "mem_mapped", mem_mapped); |
|
1903 |
qdev_set_prop_int(dev, "sun4m", 0); |
|
1904 |
qdev_init(dev); |
|
1905 |
s = sysbus_from_qdev(dev); |
|
1906 |
sysbus_connect_irq(s, 0, irq); |
|
1907 |
fdctrl = FROM_SYSBUS(fdctrl_t, s); |
|
1904 | 1908 |
if (mem_mapped) { |
1905 |
io_mem = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, |
|
1906 |
fdctrl); |
|
1907 |
cpu_register_physical_memory(io_base, 0x08, io_mem); |
|
1909 |
sysbus_mmio_map(s, 0, io_base); |
|
1908 | 1910 |
} else { |
1909 | 1911 |
register_ioport_read((uint32_t)io_base + 0x01, 5, 1, |
1910 | 1912 |
&fdctrl_read_port, fdctrl); |
... | ... | |
1916 | 1918 |
&fdctrl_write_port, fdctrl); |
1917 | 1919 |
} |
1918 | 1920 |
|
1921 |
fdctrl_init_common(fdctrl, dma_chann, io_base, fds); |
|
1922 |
|
|
1919 | 1923 |
return fdctrl; |
1920 | 1924 |
} |
1921 | 1925 |
|
1922 | 1926 |
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, |
1923 | 1927 |
BlockDriverState **fds, qemu_irq *fdc_tc) |
1924 | 1928 |
{ |
1929 |
DeviceState *dev; |
|
1930 |
SysBusDevice *s; |
|
1925 | 1931 |
fdctrl_t *fdctrl; |
1926 |
int io_mem; |
|
1927 | 1932 |
|
1928 |
fdctrl = fdctrl_init_common(irq, -1, io_base, fds); |
|
1929 |
fdctrl->sun4m = 1; |
|
1930 |
io_mem = cpu_register_io_memory(fdctrl_mem_read_strict, |
|
1931 |
fdctrl_mem_write_strict, |
|
1932 |
fdctrl); |
|
1933 |
cpu_register_physical_memory(io_base, 0x08, io_mem); |
|
1934 |
*fdc_tc = *qemu_allocate_irqs(fdctrl_handle_tc, fdctrl, 1); |
|
1933 |
dev = qdev_create(NULL, "fdc"); |
|
1934 |
qdev_set_prop_int(dev, "strict_io", 1); |
|
1935 |
qdev_set_prop_int(dev, "mem_mapped", 1); |
|
1936 |
qdev_set_prop_int(dev, "sun4m", 1); |
|
1937 |
qdev_init(dev); |
|
1938 |
s = sysbus_from_qdev(dev); |
|
1939 |
sysbus_connect_irq(s, 0, irq); |
|
1940 |
sysbus_mmio_map(s, 0, io_base); |
|
1941 |
*fdc_tc = qdev_get_gpio_in(dev, 0); |
|
1942 |
|
|
1943 |
fdctrl = FROM_SYSBUS(fdctrl_t, s); |
|
1944 |
fdctrl_init_common(fdctrl, -1, io_base, fds); |
|
1935 | 1945 |
|
1936 | 1946 |
return fdctrl; |
1937 | 1947 |
} |
1948 |
|
|
1949 |
static void fdc_init1(SysBusDevice *dev) |
|
1950 |
{ |
|
1951 |
fdctrl_t *s = FROM_SYSBUS(fdctrl_t, dev); |
|
1952 |
int io; |
|
1953 |
|
|
1954 |
sysbus_init_irq(dev, &s->irq); |
|
1955 |
qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); |
|
1956 |
if (qdev_get_prop_int(&dev->qdev, "strict_io", 0)) { |
|
1957 |
io = cpu_register_io_memory(fdctrl_mem_read_strict, |
|
1958 |
fdctrl_mem_write_strict, s); |
|
1959 |
} else { |
|
1960 |
io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, s); |
|
1961 |
} |
|
1962 |
sysbus_init_mmio(dev, 0x08, io); |
|
1963 |
} |
|
1964 |
|
|
1965 |
|
|
1966 |
static SysBusDeviceInfo fdc_info = { |
|
1967 |
.init = fdc_init1, |
|
1968 |
.qdev.name = "fdc", |
|
1969 |
.qdev.size = sizeof(fdctrl_t), |
|
1970 |
.qdev.props = (DevicePropList[]) { |
|
1971 |
{.name = "io_base", .type = PROP_TYPE_INT}, |
|
1972 |
{.name = "strict_io", .type = PROP_TYPE_INT}, |
|
1973 |
{.name = "mem_mapped", .type = PROP_TYPE_INT}, |
|
1974 |
{.name = "sun4m", .type = PROP_TYPE_INT}, |
|
1975 |
{.name = NULL} |
|
1976 |
} |
|
1977 |
}; |
|
1978 |
|
|
1979 |
static void fdc_register_devices(void) |
|
1980 |
{ |
|
1981 |
sysbus_register_withprop(&fdc_info); |
|
1982 |
} |
|
1983 |
|
|
1984 |
device_init(fdc_register_devices) |
Also available in: Unified diff