Is there anything I should do to help get that fix checked in? If yes,
please let me know.

Gabe

On Tue, Jan 18, 2022 at 9:05 PM Gabe Black <gabe.bl...@gmail.com> wrote:

> Yep, that seems to fix it for me! Thanks!
>
> Gabe
>
> On Tue, Jan 18, 2022 at 1:09 PM Volker RĂ¼melin <vr_q...@t-online.de>
> wrote:
>
>> > Hi! I'm a major contributor to the gem5 open source computer
>> > architecture simulator, and I'm trying to get SeaBIOS and FreeDOS to
>> > run on it. We've had at least some level of x86 support on our
>> > simulator for a number of years now, but we've primarily focused on 64
>> > bit mode. I've found a lot of bugs in our simulator as I've been going
>> > along, but despite my best efforts I haven't been able to find a way
>> > to blame my code for the bug I'm currently stuck on.
>> >
>> > I'm using a very stripped down configuration of SeaBIOS, and am using
>> > the serial console to interact with it since I haven't written a
>> > simulated VGA interface yet. It reads FreeDOS from their published
>> > QEMU disk image, and it starts up and prints a menu where it wants me
>> > to select from 4 different boot modes. Roughly when I send a character
>> > over the serial connection, the simulator crashes because the software
>> > running on it tried to access an address that has nothing behind it.
>> >
>> >
>> > I've been tracing this problem down, and I see an int 0x16 with code
>> > 0x1 happening, which is trying to check the keyboard status, I
>> > believe. That goes along, and eventually calls check_irqs, which calls
>> > need_hop_back which returns 1, and then calls "stack_hop_back" to call
>> > back into itself but on the "original callers stack" I 75% know what
>> > that's talking about, but I'm not 100%.
>> >
>> > Anyway, once we're on the other stack, we call into the
>> > clock_poll_irq, that calls clock_update, that calls the (inlined I
>> > think) sercon_check_event, and when that tries to
>> > SET_LOW(rx_buf[rx_bytes], byte) the bad access happens. At least I'm
>> > pretty confident that's where it happens, it could also be in one of
>> > the other lines right around there.
>>
>> This is probably a bug in src/sercon.c. rx_bytes is marked VARLOW. The
>> following code is not tested but I think
>>
>> SET_LOW(rx_buf[GET_LOW(rx_bytes)], byte);
>>
>> is correct.
>>
>> I used objdump -drS -m i8086 rom16.o for the disassembly listing.
>>      f3d8:       8e c3                   mov    %bx,%es
>>          if (GET_LOW(rx_bytes) < sizeof(rx_buf)) {
>>      f3da:       26 8a 16 79 f1          mov    %es:-0xe87,%dl
>>      f3df:       80 fa 0f                cmp    $0xf,%dl
>>      f3e2:       77 e6                   ja     f3ca <ExtraStack+0x1f2>
>>              SET_LOW(rx_buf[GET_LOW(rx_bytes)], byte);
>>      f3e4:       66 0f b6 ca             movzbl %dl,%ecx
>>      f3e8:       26 67 88 81 7c f1 00    mov %al,%es:0xf17c(%ecx)
>>      f3ef:       00
>>              SET_LOW(rx_bytes, GET_LOW(rx_bytes) + 1);
>>      f3f0:       66 42                   inc    %edx
>>      f3f2:       26 88 16 79 f1          mov    %dl,%es:-0xe87
>>              count++;
>>      f3f7:       66 46                   inc    %esi
>>      f3f9:       eb cf                   jmp    f3ca <ExtraStack+0x1f2>
>>
>> With best regards,
>> Volker
>>
>> >
>> >
>> > The problem seems to be that the variable it's trying to access is
>> > supposed to be in the "e" segment, ie with selector 0xe000 and base
>> > address 0xe0000. The code that does this is here:
>> >
>> >    fbd43: 8e c3                 mov    %bx,%es
>> >    fbd45: 26 8a 16 9d f7       mov    %es:-0x863,%dl
>> >    fbd4a: 80 fa 0f             cmp    $0xf,%dl
>> >    fbd4d: 77 e6                 ja     fbd35 <clock_update+0x6b>
>> >    fbd4f: 66 0f b6 0e 9d f7     movzbl -0x863,%ecx   <====  where it
>> > asplodes
>> >    fbd55: 26 67 88 81 a0 f7 00 mov    %al,%es:0xf7a0(%ecx)
>> >
>> > Note the comparison against 0xf, which I think is where it checks
>> > against the size of rx_buf.
>> >
>> > You can see here that this access is (I think) using the %ds register
>> > by default. It has an operand size prefix, and a 2 byte displacement
>> > of 0xf79d. Adding this to 0xe0000 gives 0xef79d, which from what I've
>> > seen is a pretty valid looking address, not far below where I have the
>> > BIOS ROM mapped in.
>> >
>> > Unfortunately when this has problems, %ds is actually 0x9d80, which
>> > gives a base of 0x9d800, which gives a linear address of 0xacf9d. This
>> > is in the middle of the (not yet implemented) VGA framebuffer which is
>> > why it dies.
>> >
>> >
>> > I then traced down why %ds has this value, and it's from the "hop
>> > back" step, specifically here:
>> >
>> >     asm volatile(
>> >         // Backup stack_pos and current %ss/%esp
>> >         "movl %6, %4\n"
>> >         "movw %%ss, %w3\n"
>> >         "movl %%esp, %6\n"
>> >         // Restore original callers' %ss/%esp
>> >         "movl -4(%4), %5\n"
>> >         "movl %5, %%ss\n"    <======== Where %ss is set
>> >         "movw %%ds:-8(%4), %%sp\n"
>> >         "movl %5, %%ds\n"    <======== Where %ds is set
>> >         // Call func
>> >
>> > Note that in this code, *both* %ss and %ds are being set, and being
>> > set to the same thing. This value *was* successfully pulled off the
>> > saved data from when the int was originally called as far as I can
>> > tell, but this value of %ds does *not* seem to be correct, since the
>> > first time it's used it causes the bad access.
>> >
>> >
>> > Could you please help me figure out what's going wrong here? Is this
>> > supposed to work out somehow, and my simulator is just wrong (my bet,
>> > but what's it doing wrong?), or is this a bug in SeaBIOS? Am I using
>> > SeaBIOS in some way it's known not to work?
>> >
>> > Please let me know if you need any other info, I'll be more than happy
>> > to get this sorted out!
>> >
>> > Gabe
>> >
>> > _______________________________________________
>> > SeaBIOS mailing list -- seabios@seabios.org
>> > To unsubscribe send an email to seabios-le...@seabios.org
>>
>>
_______________________________________________
SeaBIOS mailing list -- seabios@seabios.org
To unsubscribe send an email to seabios-le...@seabios.org

Reply via email to