Author: blueswirl Date: 2009-01-25 10:56:08 +0100 (Sun, 25 Jan 2009) New Revision: 425
Modified: openbios-devel/arch/sparc32/openbios.c openbios-devel/arch/x86/openbios.c openbios-devel/drivers/floppy.c openbios-devel/drivers/obio.c openbios-devel/drivers/pci.c openbios-devel/include/openbios/drivers.h openbios-devel/include/sparc32/io.h Log: Add support for floppy boot on Sparc32
Modified: openbios-devel/arch/sparc32/openbios.c =================================================================== --- openbios-devel/arch/sparc32/openbios.c 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/arch/sparc32/openbios.c 2009-01-25 09:56:08 UTC (rev 425) @@ -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 *hwdef;
+void setup_timers(void) +{ +} + +void udelay(unsigned int usecs) +{ +} + +void mdelay(unsigned int msecs) +{ +} + static void init_memory(void) { memory = malloc(MEMORY_SIZE);
Modified: openbios-devel/arch/x86/openbios.c =================================================================== --- openbios-devel/arch/x86/openbios.c 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/arch/x86/openbios.c 2009-01-25 09:56:08 UTC (rev 425) @@ -48,7 +48,7 @@ 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);
Modified: openbios-devel/drivers/floppy.c =================================================================== --- openbios-devel/drivers/floppy.c 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/drivers/floppy.c 2009-01-25 09:56:08 UTC (rev 425) @@ -20,22 +20,18 @@ #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 @@ 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,7 +225,36 @@ 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) { unsigned char newdor,olddor; @@ -236,7 +263,7 @@ 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 @@ { 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 @@ 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 @@ 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 @@ } 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 @@
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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@
/* 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 @@ 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 @@ 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 @@ } /* 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 @@ 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 -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 @@ }
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 @@ };
-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; }
Modified: openbios-devel/drivers/obio.c =================================================================== --- openbios-devel/drivers/obio.c 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/drivers/obio.c 2009-01-25 09:56:08 UTC (rev 425) @@ -969,12 +969,18 @@ 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"); }
Modified: openbios-devel/drivers/pci.c =================================================================== --- openbios-devel/drivers/pci.c 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/drivers/pci.c 2009-01-25 09:56:08 UTC (rev 425) @@ -443,7 +443,7 @@ { #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);
Modified: openbios-devel/include/openbios/drivers.h =================================================================== --- openbios-devel/include/openbios/drivers.h 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/include/openbios/drivers.h 2009-01-25 09:56:08 UTC (rev 425) @@ -86,7 +86,8 @@ 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,
Modified: openbios-devel/include/sparc32/io.h =================================================================== --- openbios-devel/include/sparc32/io.h 2009-01-25 07:31:15 UTC (rev 424) +++ openbios-devel/include/sparc32/io.h 2009-01-25 09:56:08 UTC (rev 425) @@ -61,7 +61,7 @@ { 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 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 @@ 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 @@ { 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 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 @@ 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 @@ { 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 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"); }