Re: [SeaBIOS] [coreboot] i915 status on x60.

2013-03-03 Thread Denis 'GNUtoo' Carikli
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.

2013-03-03 Thread Denis 'GNUtoo' Carikli
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.

2013-03-03 Thread ron minnich
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.

2013-03-03 Thread Kevin O'Connor
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

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread Kevin O'Connor
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

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread Kevin O'Connor
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.

2013-03-03 Thread ron minnich
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.

2013-03-03 Thread Peter Stuge
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.

2013-03-03 Thread Denis 'GNUtoo' Carikli
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.

2013-03-03 Thread ron minnich
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.

2013-03-03 Thread Denis 'GNUtoo' Carikli
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