diff --git a/arch/sparc32/openbios.c b/arch/sparc32/openbios.c index ea88a01..6f3f54e 100644 --- a/arch/sparc32/openbios.c +++ b/arch/sparc32/openbios.c @@ -14,6 +14,7 @@ #include "openbios/kernel.h" #include "openbios/stack.h" #include "openbios/nvram.h" +#include "../../drivers/timer.h" // XXX #include "sys_info.h" #include "openbios.h" #include "boot.h" @@ -98,6 +99,18 @@ static const struct hwdef hwdefs[] = { static const struct hwdef *hwdef; +void setup_timers(void) +{ +} + +void udelay(unsigned int usecs) +{ +} + +void mdelay(unsigned int msecs) +{ +} + static void init_memory(void) { memory = malloc(MEMORY_SIZE); diff --git a/arch/x86/openbios.c b/arch/x86/openbios.c index 85e6391..c279d05 100644 --- a/arch/x86/openbios.c +++ b/arch/x86/openbios.c @@ -48,7 +48,7 @@ arch_init( void ) ob_ide_init("/pci/isa", 0x1f0, 0x3f4, 0x170, 0x374); #endif #ifdef CONFIG_DRIVER_FLOPPY - ob_floppy_init("/isa", "floppy0"); + ob_floppy_init("/isa", "floppy0", 0x3f0, 0); #endif #ifdef CONFIG_XBOX init_video(phys_to_virt(0x3C00000), 640, 480, 32, 2560); diff --git a/drivers/floppy.c b/drivers/floppy.c index 27be853..209ec53 100644 --- a/drivers/floppy.c +++ b/drivers/floppy.c @@ -20,22 +20,18 @@ DECLARE_UNNAMED_NODE( ob_floppy, INSTALL_OPEN, 2*sizeof(int) ); #endif #define printk_err printk -#ifndef FD_BASE -#define FD_BASE 0x3f0 -#endif - #define FD_DRIVE 0 -#define FD_STATUS_A (FD_BASE + 0) /* Status register A */ -#define FD_STATUS_B (FD_BASE + 1) /* Status register B */ -#define FD_DOR (FD_BASE + 2) /* Digital Output Register */ -#define FD_TDR (FD_BASE + 3) /* Tape Drive Register */ -#define FD_STATUS (FD_BASE + 4) /* Main Status Register */ -#define FD_DSR (FD_BASE + 4) /* Data Rate Select Register (old) */ -#define FD_DATA (FD_BASE + 5) /* Data Transfer (FIFO) register */ -#define FD_DIR (FD_BASE + 7) /* Digital Input Register (read) */ -#define FD_DCR (FD_BASE + 7) /* Diskette Control Register (write)*/ +#define FD_STATUS_A (0) /* Status register A */ +#define FD_STATUS_B (1) /* Status register B */ +#define FD_DOR (2) /* Digital Output Register */ +#define FD_TDR (3) /* Tape Drive Register */ +#define FD_STATUS (4) /* Main Status Register */ +#define FD_DSR (4) /* Data Rate Select Register (old) */ +#define FD_DATA (5) /* Data Transfer (FIFO) register */ +#define FD_DIR (7) /* Digital Input Register (read) */ +#define FD_DCR (7) /* Diskette Control Register (write)*/ /* Bit of FD_STATUS_A */ #define STA_INT_PENDING 0x80 /* Interrupt Pending */ @@ -210,10 +206,12 @@ static struct floppy_fdc_state { int dtr; unsigned char dor; unsigned char version; /* FDC version code */ + void (*fdc_outb)(unsigned char data, unsigned long port); + unsigned char (*fdc_inb)(unsigned long port); + unsigned long io_base; + unsigned long mmio_base; } fdc_state; - - /* Synchronization of FDC access. */ #define FD_COMMAND_NONE -1 #define FD_COMMAND_ERROR 2 @@ -227,6 +225,35 @@ static struct floppy_fdc_state { static void show_floppy(void); static void floppy_reset(void); +/* + * IO port operations + */ +static unsigned char +ob_fdc_inb(unsigned long port) +{ + return inb(fdc_state.io_base + port); +} + +static void +ob_fdc_outb(unsigned char data, unsigned long port) +{ + outb(data, fdc_state.io_base + port); +} + +/* + * MMIO operations + */ +static unsigned char +ob_fdc_mmio_readb(unsigned long port) +{ + return *(unsigned char *)(fdc_state.mmio_base + port); +} + +static void +ob_fdc_mmio_writeb(unsigned char data, unsigned long port) +{ + *(unsigned char *)(fdc_state.mmio_base + port) = data; +} static int set_dor(char mask, char data) { @@ -236,7 +263,7 @@ static int set_dor(char mask, char data) newdor = (olddor & mask) | data; if (newdor != olddor){ fdc_state.dor = newdor; - outb(newdor, FD_DOR); + fdc_state.fdc_outb(newdor, FD_DOR); } return olddor; } @@ -246,7 +273,7 @@ static int wait_til_ready(void) { int counter, status; for (counter = 0; counter < 10000; counter++) { - status = inb(FD_STATUS); + status = fdc_state.fdc_inb(FD_STATUS); if (status & STATUS_READY) { return status; } @@ -265,7 +292,7 @@ static int output_byte(unsigned char byte) if ((status = wait_til_ready()) < 0) return status; if ((status & (STATUS_READY|STATUS_DIR|STATUS_NON_DMA)) == STATUS_READY){ - outb(byte,FD_DATA); + fdc_state.fdc_outb(byte,FD_DATA); return 0; } printk_debug("Unable to send byte %x to FDC_STATE. Status=%x\n", @@ -288,7 +315,7 @@ static int result(unsigned char *reply_buffer, int max_replies) return i; } if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) - reply_buffer[i] = inb(FD_DATA); + reply_buffer[i] = fdc_state.fdc_inb(FD_DATA); else break; } @@ -366,7 +393,7 @@ static unsigned char collect_interrupt(void) } max_sensei--; }while(((reply_buffer[0] & 0x83) != FD_DRIVE) && (nr == 2) && max_sensei); - status = inb(FD_STATUS); + status = fdc_state.fdc_inb(FD_STATUS); printk_debug("status = %x, reply_buffer=", status); for(i = 0; i < nr; i++) { printk_debug(" %x", @@ -405,7 +432,7 @@ static void set_drive(int drive) mdelay(DRIVE_H1440_SPINUP); - status = inb(FD_STATUS); + status = fdc_state.fdc_inb(FD_STATUS); printk_debug("set_drive status = %02x, new_dor = %02x\n", status, new_dor); if (status != STATUS_READY) { @@ -440,7 +467,7 @@ static void fdc_dtr(unsigned rate) return; /* Set dtr */ - outb(rate, FD_DCR); + fdc_state.fdc_outb(rate, FD_DCR); /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB) * need a stabilization period of several milliseconds to be @@ -586,11 +613,11 @@ static void reset_fdc(void) /* Irrelevant for systems with true DMA (i386). */ if (fdc_state.version >= FDC_82072A) - outb(0x80 | (fdc_state.dtr &3), FD_DSR); + fdc_state.fdc_outb(0x80 | (fdc_state.dtr &3), FD_DSR); else { - outb(fdc_state.dor & ~DOR_NO_RESET, FD_DOR); + fdc_state.fdc_outb(fdc_state.dor & ~DOR_NO_RESET, FD_DOR); udelay(FD_RESET_DELAY); - outb(fdc_state.dor, FD_DOR); + fdc_state.fdc_outb(fdc_state.dor, FD_DOR); } result(reply, MAX_REPLIES); } @@ -605,11 +632,14 @@ static void show_floppy(void) printk_debug("-------------------\n"); printk_debug("fdc_bytes: %02x %02x xx %02x %02x %02x xx %02x\n", - inb(FD_BASE + 0), inb(FD_BASE + 1), - inb(FD_BASE + 3), inb(FD_BASE + 4), inb(FD_BASE + 5), - inb(FD_BASE + 7)); + fdc_state.fdc_inb(FD_STATUS_A), + fdc_state.fdc_inb(FD_STATUS_B), + fdc_state.fdc_inb(FD_TDR), + fdc_state.fdc_inb(FD_STATUS), + fdc_state.fdc_inb(FD_DATA), + fdc_state.fdc_inb(FD_DIR)); - printk_debug("status=%x\n", inb(FD_STATUS)); + printk_debug("status=%x\n", fdc_state.fdc_inb(FD_STATUS)); printk_debug("\n"); } @@ -719,7 +749,7 @@ static int floppy_seek(unsigned track) printk_debug("nr = %d\n", nr); printk_debug("ST0 = %02x\n", reply[0]); printk_debug("PCN = %02x\n", reply[1]); - printk_debug("status = %d\n", inb(FD_STATUS)); + printk_debug("status = %d\n", fdc_state.fdc_inb(FD_STATUS)); } return success; } @@ -818,7 +848,7 @@ static int floppy_read_sectors( /* The execution stage begins when STATUS_READY&STATUS_NON_DMA is set */ do { - status = inb(FD_STATUS); + status = fdc_state.fdc_inb(FD_STATUS); status &= STATUS_READY | STATUS_NON_DMA; } while(status != (STATUS_READY|STATUS_NON_DMA)); @@ -831,7 +861,7 @@ static int floppy_read_sectors( if (status != (STATUS_READY|STATUS_DIR|STATUS_NON_DMA)) { break; } - byte = inb(FD_DATA); + byte = fdc_state.fdc_inb(FD_DATA); if ((i >= byte_offset) && (i < end_offset)) { dest[i - byte_offset] = byte; } @@ -839,12 +869,12 @@ static int floppy_read_sectors( bytes_read = i; /* The result stage begins when STATUS_NON_DMA is cleared */ - while((status = inb(FD_STATUS)) & STATUS_NON_DMA) { + while((status = fdc_state.fdc_inb(FD_STATUS)) & STATUS_NON_DMA) { /* We get extra bytes in the fifo past * the end of the sector and drop them on the floor. * Otherwise the fifo is polluted. */ - inb(FD_DATA); + fdc_state.fdc_inb(FD_DATA); } /* Did I get an error? */ result_ok = read_ok(head); @@ -995,7 +1025,7 @@ static char get_fdc_version(void) } /* get_fdc_version */ -static int floppy_init(void) +static int floppy_init(unsigned long io_base, unsigned long mmio_base) { printk_debug("floppy_init\n"); fdc_state.in_sync = 0; @@ -1004,6 +1034,15 @@ static int floppy_init(void) fdc_state.dtr = -1; fdc_state.dor = DOR_NO_RESET; fdc_state.version = FDC_UNKNOWN; + if (mmio_base) { + fdc_state.fdc_inb = ob_fdc_mmio_readb; + fdc_state.fdc_outb = ob_fdc_mmio_writeb; + } else { + fdc_state.fdc_inb = ob_fdc_inb; + fdc_state.fdc_outb = ob_fdc_outb; + } + fdc_state.io_base = io_base; + fdc_state.mmio_base = mmio_base; reset_fdc(); /* Try to determine the floppy controller type */ fdc_state.version = get_fdc_version(); @@ -1032,10 +1071,10 @@ static void floppy_reset(void) } static void -ob_floppy_initialize(int *idx) +ob_floppy_initialize(const char *path) { int props[3]; - phandle_t ph=get_cur_dev(); + phandle_t ph = find_dev(path); push_str("block"); fword("device-type"); @@ -1103,7 +1142,6 @@ ob_floppy_max_transfer(int *idx) } NODE_METHODS(ob_floppy) = { - { NULL, ob_floppy_initialize }, { "open", ob_floppy_open }, { "close", ob_floppy_close }, { "read-blocks", ob_floppy_read_blocks }, @@ -1112,12 +1150,19 @@ NODE_METHODS(ob_floppy) = { }; -int ob_floppy_init(const char *path, const char *dev_name) +int ob_floppy_init(const char *path, const char *dev_name, + unsigned long io_base, unsigned long mmio_base) { char nodebuff[128]; snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); - REGISTER_NAMED_NODE(ob_floppy, nodebuff); - floppy_init(); + if (!mmio_base) { + REGISTER_NAMED_NODE(ob_floppy, nodebuff); + ob_floppy_initialize(nodebuff); + } else { + // Already in tree and mapped + REGISTER_NODE_METHODS(ob_floppy, nodebuff); + } + floppy_init(io_base, mmio_base); return 0; } diff --git a/drivers/obio.c b/drivers/obio.c index c467ea1..860d3f0 100644 --- a/drivers/obio.c +++ b/drivers/obio.c @@ -969,12 +969,18 @@ ob_nvram_init(uint64_t base, uint64_t offset) static void ob_fd_init(uint64_t base, uint64_t offset, int intr) { + unsigned long addr; + ob_new_obio_device("SUNW,fdtwo", "block"); - ob_reg(base, offset, FD_REGS, 0); + addr = ob_reg(base, offset, FD_REGS, 1); ob_intr(intr); + fword("is-deblocker"); + + ob_floppy_init("/obio", "SUNW,fdtwo", 0, addr); + fword("finish-device"); } diff --git a/drivers/pci.c b/drivers/pci.c index 00b79a2..ecb6d07 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -443,7 +443,7 @@ int ebus_config_cb(const pci_config_t *config) { #ifdef CONFIG_DRIVER_EBUS #ifdef CONFIG_DRIVER_FLOPPY - ob_floppy_init(config->path, "fdthree"); + ob_floppy_init(config->path, "fdthree", 0x3f0ULL, 0); #endif #ifdef CONFIG_DRIVER_PC_SERIAL ob_pc_serial_init(config->path, "su", arch->io_base, 0x3f8ULL, 0); diff --git a/include/openbios/drivers.h b/include/openbios/drivers.h index af5a0d9..ae1ecf7 100644 --- a/include/openbios/drivers.h +++ b/include/openbios/drivers.h @@ -86,7 +86,8 @@ extern uint32_t cmdline_size; extern char boot_device; #endif #ifdef CONFIG_DRIVER_FLOPPY -int ob_floppy_init(const char *path, const char *dev_name); +int ob_floppy_init(const char *path, const char *dev_name, + unsigned long io_base, unsigned long mmio_base); #endif #ifdef CONFIG_DRIVER_PC_KBD void ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base, diff --git a/include/sparc32/io.h b/include/sparc32/io.h index ca4ee05..25e261d 100644 --- a/include/sparc32/io.h +++ b/include/sparc32/io.h @@ -61,7 +61,7 @@ static inline int in_8(volatile unsigned char *addr) { int ret; - __asm__ __volatile__("lduba [%1] 0x20, %0\n\t" + __asm__ __volatile__("ldub [%1], %0\n\t" "stbar\n\t" :"=r"(ret):"r"(addr):"memory"); @@ -70,7 +70,7 @@ static inline int in_8(volatile unsigned char *addr) static inline void out_8(volatile unsigned char *addr, int val) { - __asm__ __volatile__("stba %0, [%1] 0x20\n\t" + __asm__ __volatile__("stb %0, [%1]\n\t" "stbar\n\t" : : "r"(val), "r"(addr):"memory"); } @@ -80,7 +80,7 @@ static inline int in_le16(volatile unsigned short *addr) int ret; // XXX - __asm__ __volatile__("lduha [%1] 0x20, %0\n\t" + __asm__ __volatile__("lduh [%1], %0\n\t" "stbar\n\t" :"=r"(ret):"r"(addr):"memory"); @@ -91,7 +91,7 @@ static inline int in_be16(volatile unsigned short *addr) { int ret; - __asm__ __volatile__("lduha [%1] 0x20, %0\n\t" + __asm__ __volatile__("lduh [%1], %0\n\t" "stbar\n\t" :"=r"(ret):"r"(addr):"memory"); @@ -101,14 +101,14 @@ static inline int in_be16(volatile unsigned short *addr) static inline void out_le16(volatile unsigned short *addr, int val) { // XXX - __asm__ __volatile__("stha %0, [%1] 0x20\n\t" + __asm__ __volatile__("sth %0, [%1]\n\t" "stbar\n\t" : : "r"(val), "r"(addr):"memory"); } static inline void out_be16(volatile unsigned short *addr, int val) { - __asm__ __volatile__("stha %0, [%1] 0x20\n\t" + __asm__ __volatile__("sth %0, [%1]\n\t" "stbar\n\t" : : "r"(val), "r"(addr):"memory"); } @@ -118,7 +118,7 @@ static inline unsigned in_le32(volatile unsigned *addr) unsigned ret; // XXX - __asm__ __volatile__("lda [%1] 0x20, %0\n\t" + __asm__ __volatile__("ld [%1], %0\n\t" "stbar\n\t" :"=r"(ret):"r"(addr):"memory"); @@ -129,7 +129,7 @@ static inline unsigned in_be32(volatile unsigned *addr) { unsigned ret; - __asm__ __volatile__("lda [%1] 0x20, %0\n\t" + __asm__ __volatile__("ld [%1], %0\n\t" "stbar\n\t" :"=r"(ret):"r"(addr):"memory"); @@ -139,14 +139,14 @@ static inline unsigned in_be32(volatile unsigned *addr) static inline void out_le32(volatile unsigned *addr, int val) { // XXX - __asm__ __volatile__("sta %0, [%1] 0x20\n\t" + __asm__ __volatile__("st %0, [%1]\n\t" "stbar\n\t" : : "r"(val), "r"(addr):"memory"); } static inline void out_be32(volatile unsigned *addr, int val) { - __asm__ __volatile__("sta %0, [%1] 0x20\n\t" + __asm__ __volatile__("st %0, [%1]\n\t" "stbar\n\t" : : "r"(val), "r"(addr):"memory"); }