Re: Still did not succeed to boot on Lenovo Yoga C630

Hiroo Ono (小野寛生) <[email protected]>
Newsgroups gmane.os.freebsd.devel.arm
Message-ID <CANtk6SgK6n75PQ94M8CPKY5vCCEs_viQMFsJxW1kZ+412ee9AA@mail.gmail.com>
2022年12月24日(土) 10:03 Warner Losh <[email protected]>:
>
>
>
> On Fri, Dec 23, 2022 at 5:49 PM Hiroo Ono (小野寛生) <[email protected]> wrote:
>>
>> The current status of FreeBSD 14-current on Lenovo Yoga C630 is as follows:
>>
>>  1) Merging from OpenBSD's loader code made the loader boot apart from
>> 3 points (#2 to 4 ).
>>  2) when comconsole->c_init() runs the 2nd time, it seems to freeze.
>> (might be C630 specific)
>>  3) SetVirtualAddressMap() in efi_do_vmap() freezes. (might also
>> affect other snapdragon systems like Microsoft Arm Developer Kit)
>>  4) The kernel is kicked but does not start.
>>
>> 1) is quite straightforward. What needs to be changed is
>> stand/efi/loader/arch/arm64/start.S.
>
>
> Can you share what needs to be done? To my eye, we don't need any changes, so it would be good to know what you've had to do exactly.
>
>>
>> For 2), I do not know what to do. Currently, I commented out
>> comconsole from struct console *consoles[] in stand/efi/loader/conf.c
>> as a workaround. Maybe, I should write a fault handler that helps
>> returning from the fault.
>
>
> There were problems with this with HyperV on aarch64 too.
>
> Something like
> diff --git a/stand/efi/loader/efiserialio.c b/stand/efi/loader/efiserialio.c
> index 8b3f8e83e0b3..54ee39096685 100644
> --- a/stand/efi/loader/efiserialio.c
> +++ b/stand/efi/loader/efiserialio.c
> @@ -261,11 +261,11 @@ comc_probe(struct console *sc)
>                 if (comc_port == NULL)
>                         return;
>         }
> -       comc_port->baudrate = COMSPEED;
> +       comc_port->baudrate = 0;
>         comc_port->ioaddr = 0;                  /* default port */
> -       comc_port->databits = 8;                /* 8,n,1 */
> -       comc_port->parity = NoParity;           /* 8,n,1 */
> -       comc_port->stopbits = OneStopBit;       /* 8,n,1 */
> +       comc_port->databits = 0;                /* 8,n,1 */
> +       comc_port->parity = 0;          /* 8,n,1 */
> +       comc_port->stopbits = 0;        /* 8,n,1 */
>         comc_port->ignore_cd = 1;               /* ignore cd */
>         comc_port->rtsdtr_off = 0;              /* rts-dtr is on */
>         comc_port->sio = NULL;
>
> was needed.  Possibly the following would be better:
>
> diff --git a/stand/efi/loader/efiserialio.c b/stand/efi/loader/efiserialio.c
> index 8b3f8e83e0b3..54ee39096685 100644
> --- a/stand/efi/loader/efiserialio.c
> +++ b/stand/efi/loader/efiserialio.c
> @@ -494,8 +494,7 @@ comc_setup(void)
>                 return (false);
>
>         status = comc_port->sio->SetAttributes(comc_port->sio,
> -           comc_port->baudrate, 0, 0, comc_port->parity,
> -           comc_port->databits, comc_port->stopbits);
> +           0, 0, 0, 0, 0, 0);
>         if (EFI_ERROR(status))
>                 return (false);

Following change could avoid freeze in comconsole->c_init().
----------
--- a/stand/efi/loader/efiserialio.c
+++ b/stand/efi/loader/efiserialio.c
@@ -467,8 +467,10 @@ comc_speed_set(struct env_var *ev, int flags,
const void *value)
        if (comc_parse_intval(value, &speed) != CMD_OK)
                return (CMD_ERROR);

-       comc_port->baudrate = speed;
-       (void) comc_setup();
+       if (comc_port->baudrate != speed) {
+               comc_port->baudrate = speed;
+               (void) comc_setup();
+       }

        env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
----------

comc_speed_set sets new speed to comc_port->baudrate and calls comc_setup().
But if the new value of comc_port->baudrate is same as the previous
one, comc_setup() freezes at
    status = comc_port->sio->GetControl(comc_port->sio, &control);

Now, the remaining problem is that the kernel does not start.
Linux and OpenBSD run on the machine, so there should be a solution...

>> 3), I dumped each memory map's VirtualStart and PhysicalStart. All
>> VirtualStart were 0. So overwriting VirutalStart by the value of
>> PhysicalStart and running SetVirtualAddressMap should work. But in
>> reality, it doesn't.
>>   OpenBSD does not use SetVirtualAddress for arm64 and Linux seems to
>> have abandoned it for arm64 in 2019.
>>     https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=4e46c2a956215482418d7b315749fb1b6c6bc224
>>   Maybe, we also can avoid SetVirtualAddressMap (by
>> efi_disable_vmap="YES"). In this case, (as you wrote) I should change
>> the kernel to treat VA==PA if VirtualStart is 0. (OpenBSD seems to do
>> so).
>
>
> FreeBSD tends to prefer this... Our kernel needs to cope with cases where it has
> been called (many kexec environments provide PA != VA virtual mappings that we
> can't change).
>
>>
>> About 4), I am completely confused. In elf64_exec in
>> stand/efi/loader/arch/arm64/exec.c, the memory address that the kernel
>> was loaded is calculated as:
>>     entry = efi_translate(ehdr->e_entry);  // which becomes 0xb340000
>> and later kicked as:
>>     (*entry)(modulep);
>> I wrote that this calculation is doubtful, but it was right. I dumped
>> the data at the address 0xb340000 and compared it with the output of
>> objdump -D loader_lua.syms. It turned out that it matched with the
>> kernel's _start code in locore.S.
>> Putting some code that jumps to loader's ImageBase address at the
>> start of kernel's _start did not change anything, so I judged that the
>> kernel is not started at all.
>> The excerpt of the loader's memmap command output is as follows:
>>     Type           Physical           Virtual              #Pages     Attr
>>     LoaderData 0000b33ea000  000000000000  00000000  UC WC WT WB WP RP XP
>>     LoaderCode 0000bb909000  000000000000  000000d1 UC WC WT WB WP RP XP
>> From this output, I wonder if the memory attributes on Yoga C630 is
>> properly implemented, but as XP (exec protect) bit is on, I tried to
>> set it off by DXE services' SetMemoryAttributes() (with a lot of
>> transcription from the standards...).It succeeded, but the kernel
>> still did not run.
>>
>> From this tweet:
>> https://twitter.com/canadianbryan/status/1598053941270679552 and its
>> replies, the Microsoft Arm Developer Kit seems to have similar
>> problem, so if somebody succeeded to run FreeBSD on it, please share
>> the information how to do it.
>
>
> I run other arm64 machines w/o issue with the current code. I've not heard from Allan
> for his changes, nor seen any reviews come through...
>
> Where can one buy one of these systems. It seems just odd-ball enough that I can
> justify picking one up for work...

Currently, a Snapdragon system easy to purchase is the Microsoft Arm
Developer Kit, I suppose. It is about $600.
For laptops, Qualcomm has a list:
https://www.qualcomm.com/products/application/mobile-computing/laptop-device-finder

> Warner
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.