Date: Sun, 02 May 2010 15:39:55 +0200 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= <phcoder@gmail.com> To: freebsd-ia32@freebsd.org Cc: freebsd-amd64@freebsd.org, coreboot@coreboot.org Subject: FreeBSD Coreboot support Message-ID: <4BDD80AB.1020105@gmail.com>
next in thread | raw e-mail | index | archive | help
This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig6843B2440FA59F031BF68CAB Content-Type: multipart/mixed; boundary="------------040201020502090204090201" This is a multi-part message in MIME format. --------------040201020502090204090201 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hello, I was playing with loading FreeBSD using grub2 as bootloader and have met following problems: 1) FreeBSD-i386 makes BIOS calls. On coreboot they cause a crash. I propose to restructure machdep.c to call int12 only if no smap is supplied. Patch attached. Abandon keyboard rate retrieving from BIOS in sys/dev/atkbdc/atkbd.c. Or move this code to bootloader and pass the rate in environment. I'll do the patch when we decide on approach to use. sys/i386/cpufreq/smist.c is unusable and would cause panic. sys/i386/isa/vesa.c usability depends on VGA BIOS. For the last 2 cases and the future I propose to have a flag like hw.no_bios=3D1 and hw.no_video_bios=3D1 which would make vm86_intcall and= vm86_datacall return an error on intnum!=3D0x10 / intnum=3D0x10. Alternatively it's possible to catch the exception in vm8086 mode and return an error instead of panic. 2) The range 0-0x1000 isn't usable on coreboot since it contains coreboot tables which according to an IRC chat I had with devs shouldn't be overwritten. It causes an early hang on i386 or a following panic on amd64: if (basemem =3D=3D 0) panic("BIOS smap did not include a basemem segment!"); Can FreeBSD avoid using these memory chunks if they are not available? 3) On amd64 if no ACPI tables are present and using serial console userspace is able to write only 16 bytes to console. Kernel messages have no such problem. I'm confused --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------040201020502090204090201 Content-Type: text/x-diff; name="machdep.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="machdep.diff" =3D=3D=3D modified file 'sys/i386/i386/machdep.c' --- sys/i386/i386/machdep.c 2010-04-07 02:21:36 +0000 +++ sys/i386/i386/machdep.c 2010-05-02 11:48:25 +0000 @@ -2022,6 +2022,54 @@ return (1); } =20 +static void +map_bios (void) +{ + vm_paddr_t pa; + pt_entry_t *pte; + int i; + + if (basemem > 640) { + printf("Preposterous BIOS basemem of %uK, truncating to 640K\n", + basemem); + basemem =3D 640; + } +=09 + /* + * XXX if biosbasemem is now < 640, there is a `hole' + * between the end of base memory and the start of + * ISA memory. The hole may be empty or it may + * contain BIOS code or data. Map it read/write so + * that the BIOS can write to it. (Memory from 0 to + * the physical end of the kernel is mapped read-only + * to begin with and then parts of it are remapped. + * The parts that aren't remapped form holes that + * remain read-only and are unused by the kernel. + * The base memory area is below the physical end of + * the kernel and right now forms a read-only hole. + * The part of it from PAGE_SIZE to + * (trunc_page(biosbasemem * 1024) - 1) will be + * remapped and used by the kernel later.) + * + * This code is similar to the code used in + * pmap_mapdev, but since no memory needs to be + * allocated we simply change the mapping. + */ + for (pa =3D trunc_page(basemem * 1024); + pa < ISA_HOLE_START; pa +=3D PAGE_SIZE) + pmap_kenter(KERNBASE + pa, pa); + =20 + /* + * Map pages between basemem and ISA_HOLE_START, if any, r/w into + * the vm86 page table so that vm86 can scribble on them using + * the vm86 map too. XXX: why 2 ways for this and only 1 way for + * page 0, at least as initialized here? + */ + pte =3D (pt_entry_t *)vm86paddr; + for (i =3D basemem / 4; i < 160; i++) + pte[i] =3D (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; +} + /* * Populate the (physmap) array with base/bound pairs describing the * available physical memory in the system, then test this memory and @@ -2039,7 +2087,7 @@ getmemsize(int first) { int i, off, physmap_idx, pa_indx, da_indx; - int hasbrokenint12, has_smap; + int has_smap; u_long physmem_tunable; u_int extmem; struct vm86frame vmf; @@ -2074,68 +2122,11 @@ physmap_idx =3D 0; goto physmap_done; #endif=09 - hasbrokenint12 =3D 0; - TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); bzero(&vmf, sizeof(vmf)); bzero(physmap, sizeof(physmap)); basemem =3D 0; =20 /* - * Some newer BIOSes has broken INT 12H implementation which cause - * kernel panic immediately. In this case, we need to scan SMAP - * with INT 15:E820 first, then determine base memory size. - */ - if (hasbrokenint12) { - goto int15e820; - } - - /* - * Perform "base memory" related probes & setup - */ - vm86_intcall(0x12, &vmf); - basemem =3D vmf.vmf_ax; - if (basemem > 640) { - printf("Preposterous BIOS basemem of %uK, truncating to 640K\n", - basemem); - basemem =3D 640; - } - - /* - * XXX if biosbasemem is now < 640, there is a `hole' - * between the end of base memory and the start of - * ISA memory. The hole may be empty or it may - * contain BIOS code or data. Map it read/write so - * that the BIOS can write to it. (Memory from 0 to - * the physical end of the kernel is mapped read-only - * to begin with and then parts of it are remapped. - * The parts that aren't remapped form holes that - * remain read-only and are unused by the kernel. - * The base memory area is below the physical end of - * the kernel and right now forms a read-only hole. - * The part of it from PAGE_SIZE to - * (trunc_page(biosbasemem * 1024) - 1) will be - * remapped and used by the kernel later.) - * - * This code is similar to the code used in - * pmap_mapdev, but since no memory needs to be - * allocated we simply change the mapping. - */ - for (pa =3D trunc_page(basemem * 1024); - pa < ISA_HOLE_START; pa +=3D PAGE_SIZE) - pmap_kenter(KERNBASE + pa, pa); - - /* - * Map pages between basemem and ISA_HOLE_START, if any, r/w into - * the vm86 page table so that vm86 can scribble on them using - * the vm86 map too. XXX: why 2 ways for this and only 1 way for - * page 0, at least as initialized here? - */ - pte =3D (pt_entry_t *)vm86paddr; - for (i =3D basemem / 4; i < 160; i++) - pte[i] =3D (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; - -int15e820: - /* * Fetch the memory map with INT 15:E820. First, check to see * if the loader supplied it and use that if so. Otherwise, * use vm86 to invoke the BIOS call directly. @@ -2161,6 +2152,25 @@ if (!add_smap_entry(smap, physmap, &physmap_idx)) break; } else { + int hasbrokenint12 =3D 0; + + TUNABLE_INT_FETCH("hw.hasbrokenint12", &hasbrokenint12); + + /* + * Some newer BIOSes has broken INT 12H implementation which cause + * kernel panic immediately. In this case, we need to scan SMAP + * with INT 15:E820 first, then determine base memory size. + */ + if (!hasbrokenint12) { + =09 + /* + * Perform "base memory" related probes & setup + */ + vm86_intcall(0x12, &vmf); + basemem =3D vmf.vmf_ax; + =09 + map_bios ();=09 + } /* * map page 1 R/W into the kernel page table so we can use it * as a buffer. The kernel will unmap this page later. @@ -2196,29 +2206,7 @@ } } =20 - /* - * XXX this function is horribly organized and has to the same - * things that it does above here. - */ - if (basemem =3D=3D 0) - basemem =3D 640; - if (basemem > 640) { - printf( - "Preposterous BIOS basemem of %uK, truncating to 640K\n", - basemem); - basemem =3D 640; - } - - /* - * Let vm86 scribble on pages between basemem and - * ISA_HOLE_START, as above. - */ - for (pa =3D trunc_page(basemem * 1024); - pa < ISA_HOLE_START; pa +=3D PAGE_SIZE) - pmap_kenter(KERNBASE + pa, pa); - pte =3D (pt_entry_t *)vm86paddr; - for (i =3D basemem / 4; i < 160; i++) - pte[i] =3D (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U; + map_bios (); } =20 if (physmap[1] !=3D 0) --------------040201020502090204090201-- --------------enig6843B2440FA59F031BF68CAB Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iF4EAREKAAYFAkvdgLIACgkQNak7dOguQgkukwEApKiES9Fp/TTrayYcqhwI0nQo A9Zqjo7CmrGPsYlNiJUA/ROxZyTHT0AL25pDDEl1NvLSmlaaI9r14dNk9uw0s8ef =z5ZL -----END PGP SIGNATURE----- --------------enig6843B2440FA59F031BF68CAB--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BDD80AB.1020105>