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

From: Hiroo Ono (小野寛生) <hiroo.ono+freebsd_at_gmail.com>
Date: Sat, 24 Dec 2022 13:18:45 UTC
Sorry again.
The patch is needed for
* stand/efi/loader/arch/arm64/start.S
* stand/efi/loader/arch/arm64/ldscript.arm64
* stand/efi/loader/Makefile

I forgot the last one. I remade the patch for three.

2022年12月24日(土) 22:11 Hiroo Ono (小野寛生) <hiroo.ono+freebsd@gmail.com>:
>
> 2022年12月24日(土) 10:35 Hiroo Ono (小野寛生) <hiroo.ono+freebsd@gmail.com>:
> >
> > > I run other arm64 machines w/o issue with the current code.
> >
> > Yes, Qualcomm's snapdragon is weird. I saw Linux people complain about
> > it somewhere... Wanted to know  before I bought this Yoga C630.
> >
> > 2022年12月24日(土) 10:03 Warner Losh <imp@bsdimp.com>:
> > >
> > >
> > >
> > > On Fri, Dec 23, 2022 at 5:49 PM Hiroo Ono (小野寛生) <hiroo.ono+freebsd@gmail.com> 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.
> >
> > Attached is the diff to start.S. There are 3 points.
> > 1) The loader has to be aligned to 4kb.
> > 2) Proper characteristic value should be in the PE header.
> > 3) .text and .data segment have to be separate.
> >
> > It is from OpenBSD:
> > https://github.com/openbsd/src/blob/master/sys/arch/arm64/stand/efiboot/start.S
>
> Sorry patch to ldscript.arm64 was missing.
> I am going to test your serial patch now.
>
>
> > >> 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);
> > >