Re: [SeaBIOS] [coreboot] i915 status on x60.
Hi, Here are some updates: I've got screen to light up(power on + backlight) in userspace, I've put my forked code here: https://gitorious.org/gnutoo-for-coreboot/i915tool The branch is named working (thanks a lot to ron minnich for sharing his final/ directory for i915tool...without that I could not have done it because I'm still unable to reproduce his setup...) The issue now is to find a way to write to the framebuffer memory... Maybe I could use kgdb to find the framebuffer address? I've also got some help from the #intel-gfx FreeNode IRC channel: I was told that the scanout base was DSP.BASE with reguard to: git://anongit.freedesktop.org/xorg/driver/xf86-video-intel at the following tag: 2.6.3 So here's the code: int dspbase = (plane == 0 ? DSPABASE : DSPBBASE); [...] int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; [...] Stride = pScrn-displayWidth * pI830-cpp; [...] OUTREG(dspstride, Stride); [...] OUTREG(dspbase, Start + Offset); The problem is how to replace Start + Offset, the code is quite complicated and I can't probably run it since it probably requires an old userspace. I'll probably write a new mail on that. Denis. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [coreboot] i915 status on x60.
On Sun, 3 Mar 2013 14:01:35 +0100 Denis 'GNUtoo' Carikli gnu...@no-log.org wrote: So here's the code: int dspbase = (plane == 0 ? DSPABASE : DSPBBASE); [...] int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; [...] Stride = pScrn-displayWidth * pI830-cpp; [...] OUTREG(dspstride, Stride); [...] OUTREG(dspbase, Start + Offset); The problem is how to replace Start + Offset, the code is quite complicated and I can't probably run it since it probably requires an old userspace. So I followed a bit the code but gave up yesterday night(very late) here: /* Allocate aperture space for the given size and alignment, and returns the * memory allocation. * * Allocations are a minimum of a page, and will be at least page-aligned. */ static i830_memory * i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long pitch, unsigned long alignment, int flags, enum tile_format tile_format) { [...] for (scan = pI830-memory_list; scan-next != NULL; scan = scan-next) { mem-offset = ROUND_TO(scan-end, alignment); if ((flags NEED_PHYSICAL_ADDR) mem-offset pI830-stolen_size) { /* If the allocation is entirely within stolen memory, and we're * able to get the physical addresses out of the GTT and check that * it's contiguous (it ought to be), then we can do our physical * allocations there and not bother the kernel about it. This * helps avoid aperture fragmentation from our physical * allocations. */ mem-bus_addr = i830_get_stolen_physical(pScrn, mem-offset, mem-size); if (mem-bus_addr == ((uint64_t)-1)) { /* Move the start of the allocation to just past the end of * stolen memory. */ mem-offset = ROUND_TO(pI830-stolen_size, alignment); } } if ((flags NEED_NON_STOLEN) mem-offset pI830-stolen_size) { mem-offset = ROUND_TO(pI830-stolen_size, alignment); } mem-end = mem-offset + size; if (flags ALIGN_BOTH_ENDS) mem-end = ROUND_TO(mem-end, alignment); if (mem-end = scan-next-offset) break; } which is called by i830_allocate_memory(in i830_memory.c) which is called by(in i830_allocate_2d_memory in i830_memory.c) : pI830-front_buffer = i830_allocate_framebuffer(pScrn, pI830, pI830-FbMemBox, FALSE); Then we have in i830PipeSetBase(in i830_display.c): Start = pI830-front_buffer-offset; For the offset we have in the same file, same function: Offset = ((y * pScrn-displayWidth + x) * pI830-cpp); I don't know what does x and y represents, maybe they are 0? Denis. So I followed a bit the code but gave up yesterday night(very late) here: /* Allocate aperture space for the given size and alignment, and returns the * memory allocation. * * Allocations are a minimum of a page, and will be at least page-aligned. */ static i830_memory * i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long pitch, unsigned long alignment, int flags, enum tile_format tile_format) { [...] for (scan = pI830-memory_list; scan-next != NULL; scan = scan-next) { mem-offset = ROUND_TO(scan-end, alignment); if ((flags NEED_PHYSICAL_ADDR) mem-offset pI830-stolen_size) { /* If the allocation is entirely within stolen memory, and we're * able to get the physical addresses out of the GTT and check that * it's contiguous (it ought to be), then we can do our physical * allocations there and not bother the kernel about it. This * helps avoid aperture fragmentation from our physical * allocations. */ mem-bus_addr = i830_get_stolen_physical(pScrn, mem-offset, mem-size); if (mem-bus_addr == ((uint64_t)-1)) { /* Move the start of the allocation to just past the end of * stolen memory. */ mem-offset = ROUND_TO(pI830-stolen_size, alignment); } } if ((flags NEED_NON_STOLEN) mem-offset pI830-stolen_size) { mem-offset = ROUND_TO(pI830-stolen_size, alignment); } mem-end = mem-offset + size; if (flags ALIGN_BOTH_ENDS) mem-end = ROUND_TO(mem-end, alignment); if (mem-end = scan-next-offset) break; } which is called by i830_allocate_memory(in i830_memory.c) which is called by(in i830_allocate_2d_memory in i830_memory.c) :
Re: [SeaBIOS] [coreboot] i915 status on x60.
I did not have time to read all your code, will try later. To get to the frame buffer on sandybridge, you just read one of the BARs, I think i't BAR 4. That won't work on the x60? ron ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 1/2] Separate out 16bit PCI-BIOS entry point from regular int 0x1a entry point.
The PCI-BIOS entry point can be called in 16bit protected mode, so separate its entry code from the legacy 0x1a code. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/clock.c | 1 - src/config.h| 2 +- src/pcibios.c | 16 src/post.c | 2 +- src/romlayout.S | 15 +-- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/clock.c b/src/clock.c index 79b18f9..2ab6adb 100644 --- a/src/clock.c +++ b/src/clock.c @@ -552,7 +552,6 @@ handle_1a(struct bregs *regs) case 0x05: handle_1a05(regs); break; case 0x06: handle_1a06(regs); break; case 0x07: handle_1a07(regs); break; -case 0xb1: handle_1ab1(regs); break; default: handle_1aXX(regs); break; } } diff --git a/src/config.h b/src/config.h index 0b9b1ab..8b888b9 100644 --- a/src/config.h +++ b/src/config.h @@ -94,7 +94,7 @@ #define DEBUG_ISR_hwpic2 5 #define DEBUG_HDL_pnp 1 #define DEBUG_HDL_pmm 1 -#define DEBUG_HDL_pcibios32 9 +#define DEBUG_HDL_pcibios 9 #define DEBUG_HDL_apm 9 #define DEBUG_unimplemented 2 diff --git a/src/pcibios.c b/src/pcibios.c index 0f3ec5b..3c5f519 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -201,19 +201,19 @@ handle_1ab1(struct bregs *regs) } } +// Entry point for pci bios functions. +void VISIBLE16 VISIBLE32SEG +handle_pcibios(struct bregs *regs) +{ +debug_enter(regs, DEBUG_HDL_pcibios); +handle_1ab1(regs); +} + / * 32bit interface / -// Entry point for 32bit pci bios functions. -void VISIBLE32SEG -handle_pcibios32(struct bregs *regs) -{ -debug_enter(regs, DEBUG_HDL_pcibios32); -handle_1ab1(regs); -} - struct bios32_s { u32 signature; u32 entry; diff --git a/src/post.c b/src/post.c index 4d3262f..ff201fa 100644 --- a/src/post.c +++ b/src/post.c @@ -64,7 +64,7 @@ ivt_init(void) SET_IVT(0x17, FUNC16(entry_17)); SET_IVT(0x18, FUNC16(entry_18)); SET_IVT(0x19, FUNC16(entry_19_official)); -SET_IVT(0x1a, FUNC16(entry_1a)); +SET_IVT(0x1a, FUNC16(entry_1a_official)); SET_IVT(0x40, FUNC16(entry_40)); // INT 60h-66h reserved for user interrupt diff --git a/src/romlayout.S b/src/romlayout.S index b1628ef..b152b3e 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -334,19 +334,26 @@ entry_apm32: popfl lretl -// PCI-BIOS 32bit entry point +// PCI-BIOS entry points DECLFUNC entry_pcibios32 entry_pcibios32: pushfl pushl %gs // Backup %gs and set %gs=%ds pushl %ds popl %gs -ENTRY_ARG_ESP _cfunc32seg_handle_pcibios32 +ENTRY_ARG_ESP _cfunc32seg_handle_pcibios popl %gs popfl lretl +.code16gcc +DECLFUNC entry_pcibios16 +entry_pcibios16: +ENTRY_ARG handle_pcibios +iretw + // BIOS32 support +.code32 DECLFUNC entry_bios32 entry_bios32: pushfl @@ -600,6 +607,10 @@ entry_10_0x0f: // 0xfa6e - vgafont8 in font.c ORG 0xfe6e +.global entry_1a_official +entry_1a_official: +cmpb $0xb1, %ah +je entry_pcibios16 // PCIBIOS calls can be in protected mode IRQ_ENTRY_ARG 1a ORG 0xfea5 -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 0/2] Use extra stack for all 16bit irq entry points
This series creates a config option for using the extra stack for all legacy 16bit irq entry points, and it defaults the option on. By using this internal stack, SeaBIOS doesn't use much of the caller's stack and it makes it less likely a stack overflow will occur. However, using an internal stack could break programs that call the BIOS in 16bit protected mode. This series was discussed about a year ago. There haven't been any examples located where this breaks OSes, and it is known to improve some really old OSes (eg, DOS 1.0). It is a config option, so if it can be disabled to aid in testing. Kevin O'Connor (2): Separate out 16bit PCI-BIOS entry point from regular int 0x1a entry point. Support using the extra stack for all 16bit irq entry points. src/Kconfig | 9 +++ src/clock.c | 1 - src/config.h| 2 +- src/pcibios.c | 16 ++--- src/post.c | 2 +- src/romlayout.S | 73 +++-- 6 files changed, 90 insertions(+), 13 deletions(-) -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 2/2] Support using the extra stack for all 16bit irq entry points.
Using the internal stack reduces the amount of space that SeaBIOS uses on the caller's stack. This is known to help some very old operating systems (like DOS 1.0). However, there is a possibility that this will break any operating systems that calls a legacy 16bit irq in 16bit protected mode (no OSes have yet to be identified as doing this), so make the ability config dependent. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/Kconfig | 9 + src/romlayout.S | 58 + 2 files changed, 67 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index 98a6642..3141069 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -103,6 +103,15 @@ endchoice default y help Support floppy images in coreboot flash. +config ENTRY_EXTRASTACK +bool Use internal stack for 16bit interrupt entry points +default y +help +Utilize an internal stack for all the legacy 16bit +interrupt entry points. This reduces the amount of space +on the caller's stack that SeaBIOS uses. This may +adversely impact any legacy operating systems that call +the BIOS in 16bit protected mode. endmenu diff --git a/src/romlayout.S b/src/romlayout.S index b152b3e..291b798 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -480,6 +480,60 @@ irqentry_extrastack: popw %ds iretw +// Main entry point for interrupts handled on extra stack +DECLFUNC irqentry_arg_extrastack +irqentry_arg_extrastack: +cli +cld +pushw %ds // Set %ds:%eax to space on ExtraStack +pushl %eax +movl $_zonelow_seg, %eax +movl %eax, %ds +movl StackPos, %eax +subl $BREGS_size+8, %eax +popl BREGS_eax(%eax)// Backup registers +popw BREGS_ds(%eax) +movl %edi, BREGS_edi(%eax) +movl %esi, BREGS_esi(%eax) +movl %ebp, BREGS_ebp(%eax) +movl %ebx, BREGS_ebx(%eax) +movl %edx, BREGS_edx(%eax) +movl %ecx, BREGS_ecx(%eax) +popl %ecx +movw %es, BREGS_es(%eax) +movl %esp, BREGS_size+0(%eax) +movzwl %sp, %esp +movw %ss, BREGS_size+4(%eax) +movl (%esp), %edx +movl %edx, BREGS_code(%eax) +movw 4(%esp), %dx +movw %dx, BREGS_flags(%eax) + +movw %ds, %dx // Setup %ss/%esp and call function +movw %dx, %ss +movl %eax, %esp +calll *%ecx + +movl %esp, %eax // Restore registers and return +movw BREGS_size+4(%eax), %ss +movl BREGS_size+0(%eax), %esp +popl %edx +popw %dx +pushw BREGS_flags(%eax) +pushl BREGS_code(%eax) +movl BREGS_edi(%eax), %edi +movl BREGS_esi(%eax), %esi +movl BREGS_ebp(%eax), %ebp +movl BREGS_ebx(%eax), %ebx +movl BREGS_edx(%eax), %edx +movl BREGS_ecx(%eax), %ecx +movw BREGS_es(%eax), %es +pushw BREGS_ds(%eax) +pushl BREGS_eax(%eax) +popl %eax +popw %ds +iretw + // Main entry point for interrupts with args DECLFUNC irqentryarg irqentryarg: @@ -504,7 +558,11 @@ irqentryarg: .global entry_\num entry_\num : pushl $ handle_\num +#if CONFIG_ENTRY_EXTRASTACK +jmp irqentry_arg_extrastack +#else jmp irqentryarg +#endif .endm .macro DECL_IRQ_ENTRY_ARG num -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 0/8] Floppy cleanup and fixes for latest QEMU
Recent versions of QEMU are picky about the data rate specified when performing floppy transfers (see QEMU commit 844f65d6). This broke the SeaBIOS handling of legacy disk sizes (eg, 360K). This series cleans up the low-level floppy transfer code and adds in media sensing code to make old floppies work under QEMU again. (It's unclear if this will improve handling on real hardware.) -Kevin Kevin O'Connor (8): Minor - improve comments and grouping of handle_08(). floppy: Introduce 'struct floppy_pio_s' for floppy PIO ops. floppy: Cleanup floppy irq wait handling. floppy: Clean up Check Interrupt Status code. floppy: Move recalibration and results parsing to floppy_cmd(). floppy: Improve floppy_pio() error checking. floppy: Implement media format sensing. floppy: Actually do controller reset in floppy_reset(). src/biosvar.h | 2 +- src/clock.c | 6 +- src/floppy.c | 552 +- 3 files changed, 321 insertions(+), 239 deletions(-) -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 3/8] floppy: Cleanup floppy irq wait handling.
Rename FRS_TIMEOUT to FRS_IRQ - the flag indicates that an irq has been received - it isn't directly related to timeouts. On a timeout event, disable the floppy controller instead of doing a full reset. Also, perform the disable directly in floppy_wait_irq(). Always wait for the floppy irq after enabling the controller and after a recalibrate command. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/biosvar.h | 2 +- src/floppy.c | 88 +-- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/biosvar.h b/src/biosvar.h index 520fc3e..bbb196a 100644 --- a/src/biosvar.h +++ b/src/biosvar.h @@ -120,7 +120,7 @@ struct bios_data_area_s { } PACKED; // BDA floppy_recalibration_status bitdefs -#define FRS_TIMEOUT (17) +#define FRS_IRQ (17) // BDA rtc_wait_flag bitdefs #define RWS_WAIT_PENDING (10) diff --git a/src/floppy.c b/src/floppy.c index 34fb1b0..ddefdc6 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -164,63 +164,59 @@ find_floppy_type(u32 size) / static void -floppy_reset_controller(void) +floppy_disable_controller(void) { -// Reset controller -u8 val8 = inb(PORT_FD_DOR); -outb(val8 ~0x04, PORT_FD_DOR); -outb(val8 | 0x04, PORT_FD_DOR); - -// Wait for controller to come out of reset -while ((inb(PORT_FD_STATUS) 0xc0) != 0x80) -; +outb(inb(PORT_FD_DOR) ~0x04, PORT_FD_DOR); } static int -wait_floppy_irq(void) +floppy_wait_irq(void) { -ASSERT16(); -u8 frs; +u8 frs = GET_BDA(floppy_recalibration_status); +SET_BDA(floppy_recalibration_status, frs ~FRS_IRQ); for (;;) { -if (!GET_BDA(floppy_motor_counter)) -return -1; +if (!GET_BDA(floppy_motor_counter)) { +floppy_disable_controller(); +return DISK_RET_ETIMEOUT; +} frs = GET_BDA(floppy_recalibration_status); -if (frs FRS_TIMEOUT) +if (frs FRS_IRQ) break; // Could use yield_toirq() here, but that causes issues on // bochs, so use yield() instead. yield(); } -frs = ~FRS_TIMEOUT; -SET_BDA(floppy_recalibration_status, frs); -return 0; +SET_BDA(floppy_recalibration_status, frs ~FRS_IRQ); +return DISK_RET_SUCCESS; } -static void -floppy_prepare_controller(u8 floppyid) +static int +floppy_enable_controller(void) { -u8 frs = GET_BDA(floppy_recalibration_status); -SET_BDA(floppy_recalibration_status, frs ~FRS_TIMEOUT); - -// turn on motor of selected drive, DMA int enabled, normal operation -u8 prev_reset = inb(PORT_FD_DOR) 0x04; -u8 dor = 0x10; -if (floppyid) -dor = 0x20; -dor |= 0x0c; -dor |= floppyid; -outb(dor, PORT_FD_DOR); +outb(inb(PORT_FD_DOR) | 0x04, PORT_FD_DOR); +return floppy_wait_irq(); +} +static int +floppy_select_drive(u8 floppyid) +{ // reset the disk motor timeout value of INT 08 SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); -// wait for drive readiness -while ((inb(PORT_FD_STATUS) 0xc0) != 0x80) -; +// Enable controller if it isn't running. +u8 dor = inb(PORT_FD_DOR); +if (!(dor 0x04)) { +int ret = floppy_enable_controller(); +if (ret) +return ret; +} -if (!prev_reset) -wait_floppy_irq(); +// Turn on motor of selected drive, DMA int enabled, normal operation +dor = (floppyid ? 0x20 : 0x10) | 0x0c | floppyid; +outb(dor, PORT_FD_DOR); + +return DISK_RET_SUCCESS; } struct floppy_pio_s { @@ -233,7 +229,13 @@ struct floppy_pio_s { static int floppy_pio(struct floppy_pio_s *pio) { -floppy_prepare_controller(pio-data[1] 1); +int ret = floppy_select_drive(pio-data[1] 1); +if (ret) +return ret; + +// wait for drive readiness +while ((inb(PORT_FD_STATUS) 0xc0) != 0x80) +; // send command to controller int i; @@ -241,11 +243,9 @@ floppy_pio(struct floppy_pio_s *pio) outb(pio-data[i], PORT_FD_DATA); if (pio-waitirq) { -int ret = wait_floppy_irq(); -if (ret) { -floppy_reset_controller(); -return DISK_RET_ETIMEOUT; -} +int ret = floppy_wait_irq(); +if (ret) +return ret; } if (!pio-resplen) @@ -330,7 +330,7 @@ floppy_drive_recal(u8 floppyid) struct floppy_pio_s pio; pio.cmdlen = 2; pio.resplen = 0; -pio.waitirq = 0; +pio.waitirq = 1; pio.data[0] = 0x07; // 07: Recalibrate pio.data[1] = floppyid; // 0=drive0, 1=drive1 floppy_pio(pio); @@ -617,7 +617,7 @@ handle_0e(void) } // diskette interrupt has occurred u8 frs = GET_BDA(floppy_recalibration_status); -SET_BDA(floppy_recalibration_status, frs | FRS_TIMEOUT); +SET_BDA(floppy_recalibration_status, frs | FRS_IRQ); eoi_pic1(); } -- 1.7.11.7
[SeaBIOS] [PATCH 4/8] floppy: Clean up Check Interrupt Status code.
Don't run the Check Interrupt Status command from the floppy hardware interrupt handler. Instead, run it where it is needed - after controller startup and after a recalibration command. Also, use floppy_pio() to issue the command instead of open coding it. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/floppy.c | 105 ++- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/src/floppy.c b/src/floppy.c index ddefdc6..f3dba38 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -191,34 +191,6 @@ floppy_wait_irq(void) return DISK_RET_SUCCESS; } -static int -floppy_enable_controller(void) -{ -outb(inb(PORT_FD_DOR) | 0x04, PORT_FD_DOR); -return floppy_wait_irq(); -} - -static int -floppy_select_drive(u8 floppyid) -{ -// reset the disk motor timeout value of INT 08 -SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); - -// Enable controller if it isn't running. -u8 dor = inb(PORT_FD_DOR); -if (!(dor 0x04)) { -int ret = floppy_enable_controller(); -if (ret) -return ret; -} - -// Turn on motor of selected drive, DMA int enabled, normal operation -dor = (floppyid ? 0x20 : 0x10) | 0x0c | floppyid; -outb(dor, PORT_FD_DOR); - -return DISK_RET_SUCCESS; -} - struct floppy_pio_s { u8 cmdlen; u8 resplen; @@ -229,10 +201,6 @@ struct floppy_pio_s { static int floppy_pio(struct floppy_pio_s *pio) { -int ret = floppy_select_drive(pio-data[1] 1); -if (ret) -return ret; - // wait for drive readiness while ((inb(PORT_FD_STATUS) 0xc0) != 0x80) ; @@ -262,6 +230,43 @@ floppy_pio(struct floppy_pio_s *pio) return DISK_RET_SUCCESS; } +static int +floppy_enable_controller(void) +{ +outb(inb(PORT_FD_DOR) | 0x04, PORT_FD_DOR); +int ret = floppy_wait_irq(); +if (ret) +return ret; + +struct floppy_pio_s pio; +pio.cmdlen = 1; +pio.resplen = 2; +pio.waitirq = 0; +pio.data[0] = 0x08; // 08: Check Interrupt Status +return floppy_pio(pio); +} + +static int +floppy_select_drive(u8 floppyid) +{ +// reset the disk motor timeout value of INT 08 +SET_BDA(floppy_motor_counter, FLOPPY_MOTOR_TICKS); + +// Enable controller if it isn't running. +u8 dor = inb(PORT_FD_DOR); +if (!(dor 0x04)) { +int ret = floppy_enable_controller(); +if (ret) +return ret; +} + +// Turn on motor of selected drive, DMA int enabled, normal operation +dor = (floppyid ? 0x20 : 0x10) | 0x0c | floppyid; +outb(dor, PORT_FD_DOR); + +return DISK_RET_SUCCESS; +} + // Perform a floppy transfer command (setup DMA and issue PIO). static int floppy_cmd(struct disk_op_s *op, int count, struct floppy_pio_s *pio) @@ -298,9 +303,12 @@ floppy_cmd(struct disk_op_s *op, int count, struct floppy_pio_s *pio) outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 +int ret = floppy_select_drive(pio-data[1] 1); +if (ret) +return ret; pio-resplen = 7; pio-waitirq = 1; -int ret = floppy_pio(pio); +ret = floppy_pio(pio); if (ret) return ret; @@ -323,9 +331,13 @@ set_diskette_current_cyl(u8 floppyid, u8 cyl) SET_BDA(floppy_track[floppyid], cyl); } -static void +static int floppy_drive_recal(u8 floppyid) { +int ret = floppy_select_drive(floppyid); +if (ret) +return ret; + // send Recalibrate command (2 bytes) to controller struct floppy_pio_s pio; pio.cmdlen = 2; @@ -333,11 +345,22 @@ floppy_drive_recal(u8 floppyid) pio.waitirq = 1; pio.data[0] = 0x07; // 07: Recalibrate pio.data[1] = floppyid; // 0=drive0, 1=drive1 -floppy_pio(pio); +ret = floppy_pio(pio); +if (ret) +return ret; + +pio.cmdlen = 1; +pio.resplen = 2; +pio.waitirq = 0; +pio.data[0] = 0x08; // 08: Check Interrupt Status +ret = floppy_pio(pio); +if (ret) +return ret; u8 frs = GET_BDA(floppy_recalibration_status); SET_BDA(floppy_recalibration_status, frs | (1floppyid)); set_diskette_current_cyl(floppyid, 0); +return DISK_RET_SUCCESS; } static int @@ -392,7 +415,9 @@ check_recal_drive(struct drive_s *drive_g) return DISK_RET_SUCCESS; // Recalibrate drive. -floppy_drive_recal(floppyid); +int ret = floppy_drive_recal(floppyid); +if (ret) +return ret; // Sense media. return floppy_media_sense(drive_g); @@ -607,14 +632,6 @@ handle_0e(void) return; debug_isr(DEBUG_ISR_0e); -if ((inb(PORT_FD_STATUS) 0xc0) != 0xc0) { -outb(0x08, PORT_FD_DATA); // sense interrupt status -while ((inb(PORT_FD_STATUS) 0xc0) != 0xc0) -; -do { -inb(PORT_FD_DATA); -} while ((inb(PORT_FD_STATUS) 0xc0) == 0xc0); -} // diskette interrupt has occurred u8 frs = GET_BDA(floppy_recalibration_status);
[SeaBIOS] [PATCH 6/8] floppy: Improve floppy_pio() error checking.
The controller can be busy on a response without it being an error. Don't spin infinitely if status isn't what is expected. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/floppy.c | 60 ++-- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/floppy.c b/src/floppy.c index 58fc7dd..91d3565 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -23,6 +23,7 @@ #define FLOPPY_FILLBYTE 0xf6 #define FLOPPY_GAPLEN 0x1B #define FLOPPY_FORMAT_GAPLEN 0x6c +#define FLOPPY_PIO_TIMEOUT 1000 // New diskette parameter table adding 3 parameters from IBM // Since no provisions are made for multiple drive types, most @@ -201,31 +202,54 @@ struct floppy_pio_s { static int floppy_pio(struct floppy_pio_s *pio) { -// wait for drive readiness -while ((inb(PORT_FD_STATUS) 0xc0) != 0x80) -; - -// send command to controller -int i; -for (i=0; ipio-cmdlen; i++) -outb(pio-data[i], PORT_FD_DATA); +// Send command to controller. +u64 end = calc_future_tsc(FLOPPY_PIO_TIMEOUT); +int i = 0; +for (;;) { +u8 sts = inb(PORT_FD_STATUS); +if (!(sts 0x80)) { +if (check_tsc(end)) { +floppy_disable_controller(); +return DISK_RET_ETIMEOUT; +} +continue; +} +if (sts 0x40) { +floppy_disable_controller(); +return DISK_RET_ECONTROLLER; +} +outb(pio-data[i++], PORT_FD_DATA); +if (i = pio-cmdlen) +break; +} +// Wait for command to complete. if (pio-waitirq) { int ret = floppy_wait_irq(); if (ret) return ret; } -if (!pio-resplen) -return DISK_RET_SUCCESS; - -// check port 3f4 for accessibility to status bytes -if ((inb(PORT_FD_STATUS) 0xc0) != 0xc0) -return DISK_RET_ECONTROLLER; - -// read return status bytes from controller -for (i=0; ipio-resplen; i++) -pio-data[i] = inb(PORT_FD_DATA); +// Read response from controller. +end = calc_future_tsc(FLOPPY_PIO_TIMEOUT); +i = 0; +for (;;) { +u8 sts = inb(PORT_FD_STATUS); +if (!(sts 0x80)) { +if (check_tsc(end)) { +floppy_disable_controller(); +return DISK_RET_ETIMEOUT; +} +continue; +} +if (i = pio-resplen) +break; +if (!(sts 0x40)) { +floppy_disable_controller(); +return DISK_RET_ECONTROLLER; +} +pio-data[i++] = inb(PORT_FD_DATA); +} return DISK_RET_SUCCESS; } -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 7/8] floppy: Implement media format sensing.
Check for lower capacity media in the floppy drive and set the corresponding controller data rate for it. Signed-off-by: Kevin O'Connor ke...@koconnor.net --- src/floppy.c | 123 +-- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/src/floppy.c b/src/floppy.c index 91d3565..e335e86 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -52,29 +52,37 @@ struct floppy_dbt_s diskette_param_table VAR16FIXED(0xefc7); struct floppyinfo_s { struct chs_s chs; -u8 config_data; -u8 media_state; +u8 floppy_size; +u8 data_rate; }; +#define FLOPPY_SIZE_525 0x01 +#define FLOPPY_SIZE_350 0x02 + +#define FLOPPY_RATE_500K 0x00 +#define FLOPPY_RATE_300K 0x01 +#define FLOPPY_RATE_250K 0x02 +#define FLOPPY_RATE_1M 0x03 + struct floppyinfo_s FloppyInfo[] VARFSEG = { // Unknown { {0, 0, 0}, 0x00, 0x00}, // 1 - 360KB, 5.25 - 2 heads, 40 tracks, 9 sectors -{ {2, 40, 9}, 0x00, 0x25}, +{ {2, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K}, // 2 - 1.2MB, 5.25 - 2 heads, 80 tracks, 15 sectors -{ {2, 80, 15}, 0x00, 0x25}, +{ {2, 80, 15}, FLOPPY_SIZE_525, FLOPPY_RATE_500K}, // 3 - 720KB, 3.5 - 2 heads, 80 tracks, 9 sectors -{ {2, 80, 9}, 0x00, 0x17}, +{ {2, 80, 9}, FLOPPY_SIZE_350, FLOPPY_RATE_250K}, // 4 - 1.44MB, 3.5 - 2 heads, 80 tracks, 18 sectors -{ {2, 80, 18}, 0x00, 0x17}, +{ {2, 80, 18}, FLOPPY_SIZE_350, FLOPPY_RATE_500K}, // 5 - 2.88MB, 3.5 - 2 heads, 80 tracks, 36 sectors -{ {2, 80, 36}, 0xCC, 0xD7}, +{ {2, 80, 36}, FLOPPY_SIZE_350, FLOPPY_RATE_1M}, // 6 - 160k, 5.25 - 1 heads, 40 tracks, 8 sectors -{ {1, 40, 8}, 0x00, 0x27}, +{ {1, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K}, // 7 - 180k, 5.25 - 1 heads, 40 tracks, 9 sectors -{ {1, 40, 9}, 0x00, 0x27}, +{ {1, 40, 9}, FLOPPY_SIZE_525, FLOPPY_RATE_300K}, // 8 - 320k, 5.25 - 2 heads, 40 tracks, 8 sectors -{ {2, 40, 8}, 0x00, 0x27}, +{ {2, 40, 8}, FLOPPY_SIZE_525, FLOPPY_RATE_250K}, }; struct drive_s * @@ -335,44 +343,69 @@ floppy_drive_recal(u8 floppyid) } static int +floppy_drive_readid(u8 floppyid, u8 data_rate, u8 head) +{ +int ret = floppy_select_drive(floppyid); +if (ret) +return ret; + +// Set data rate. +outb(data_rate, PORT_FD_DIR); + +// send Read Sector Id command +struct floppy_pio_s pio; +pio.cmdlen = 2; +pio.resplen = 7; +pio.waitirq = 1; +pio.data[0] = 0x4a; // 0a: Read Sector Id +pio.data[1] = (head 2) | floppyid; // HD DR1 DR2 +ret = floppy_pio(pio); +if (ret) +return ret; +if (pio.data[0] 0xc0) +return -1; +return 0; +} + +static int floppy_media_sense(struct drive_s *drive_g) { -// for now cheat and get drive type from CMOS, -// assume media is same as drive type - -// ** config_data ** -// Bitfields for diskette media control: -// Bit(s) Description (Table M0028) -// 7-6 last data rate set by controller -//00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps -// 5-4 last diskette drive step rate selected -//00=0Ch, 01=0Dh, 10=0Eh, 11=0Ah -// 3-2 {data rate at start of operation} -// 1-0 reserved - -// ** media_state ** -// Bitfields for diskette drive media state: -// Bit(s) Description (Table M0030) -// 7-6 data rate -//00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps -// 5 double stepping required (e.g. 360kB in 1.2MB) -// 4 media type established -// 3 drive capable of supporting 4MB media -// 2-0 on exit from BIOS, contains -//000 trying 360kB in 360kB -//001 trying 360kB in 1.2MB -//010 trying 1.2MB in 1.2MB -//011 360kB in 360kB established -//100 360kB in 1.2MB established -//101 1.2MB in 1.2MB established -//110 reserved -//111 all other formats/drives - -u8 ftype = GET_GLOBAL(drive_g-floppy_type); -SET_BDA(floppy_last_data_rate, GET_GLOBAL(FloppyInfo[ftype].config_data)); +u8 ftype = GET_GLOBAL(drive_g-floppy_type), stype = ftype; u8 floppyid = GET_GLOBAL(drive_g-cntl_id); -SET_BDA(floppy_media_state[floppyid] -, GET_GLOBAL(FloppyInfo[ftype].media_state)); + +u8 data_rate = GET_GLOBAL(FloppyInfo[stype].data_rate); +int ret = floppy_drive_readid(floppyid, data_rate, 0); +if (ret) { +// Attempt media sense. +for (stype=1; ; stype++) { +if (stype = ARRAY_SIZE(FloppyInfo)) +return DISK_RET_EMEDIA; +if (stype==ftype +|| (GET_GLOBAL(FloppyInfo[stype].floppy_size) +!= GET_GLOBAL(FloppyInfo[ftype].floppy_size)) +|| (GET_GLOBAL(FloppyInfo[stype].chs.heads) + GET_GLOBAL(FloppyInfo[ftype].chs.heads)) +|| (GET_GLOBAL(FloppyInfo[stype].chs.cylinders) +
Re: [SeaBIOS] [coreboot] i915 status on x60.
you need to get the physical frame buffer address from the hardware and then mmap that in user mode. It doesn't much matter what the kernel things it is. ron ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [coreboot] i915 status on x60.
ron minnich wrote: you need to get the physical frame buffer address from the hardware and then mmap that in user mode. Yes, that's what he has been doing. The BAR points to some address which doesn't remember writes. //Peter ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [coreboot] i915 status on x60.
On Sun, 3 Mar 2013 20:35:48 +0100 Denis 'GNUtoo' Carikli gnu...@no-log.org wrote: common.c maps the framebuffer and then I do that with the virtual address: (gdb) set {int}0xa7d38000 = 0xff (gdb) p/x {int}0xa7d38000 $1 = 0x0 0xa7d38000 points or at the beginning of the bar, or at address of the framebuffer(I took it from the kernel with kgdb). I am told by phcoder on IRC that I've to activate the access to VRAM... it seems that setgtt does that, but what parameters should I give it? Denis. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [coreboot] i915 status on x60.
setgtt is only for hardware with a gtt. Again, I'm not familiar with the hardware on this laptop. Does it have a gtt? ron ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [coreboot] i915 status on x60.
On Sun, 3 Mar 2013 09:21:11 -0800 ron minnich rminn...@gmail.com wrote: I did not have time to read all your code, will try later. To get to the frame buffer on sandybridge, you just read one of the BARs, I think i't BAR 4. That won't work on the x60? I just found out that the bar2 where the framebuffer is on the x60 isn't mapped correctly: common.c maps the framebuffer and then I do that with the virtual address: (gdb) set {int}0xa7d38000 = 0xff (gdb) p/x {int}0xa7d38000 $1 = 0x0 0xa7d38000 points or at the beginning of the bar, or at address of the framebuffer(I took it from the kernel with kgdb). I am told by phcoder on IRC that I've to activate the access to VRAM... Denis. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios