On Tue, Apr 23, 2013 at 08:23:44PM +0300, Michael S. Tsirkin wrote: > On Mon, Apr 22, 2013 at 08:38:58PM -0400, Kevin O'Connor wrote: > > On Mon, Apr 22, 2013 at 10:03:01AM +0300, Michael S. Tsirkin wrote: > > > On Sun, Apr 21, 2013 at 08:39:41PM -0400, Kevin O'Connor wrote: > > > > On Sun, Apr 21, 2013 at 11:41:48PM +0300, Michael S. Tsirkin wrote: > > > > > Okay I'm pretty close to posting some patches > > > > > that advance this project further, but wanted to > > > > > check something beforehand: there are several tables > > > > > that point to other tables (for example: FADT points > > > > > to DSDT). What I did is provide a list of fixups > > > > > such that bios can patch in pointers without > > > > > any need to understand what's what. > > > > > Thoughts? > > > > > > > > For the RSDP, RSDT, and FADT I think SeaBIOS should just update those > > > > tables to set the pointers within them and then recalculate the > > > > checksum. I don't think anything complex is needed - it's easy for > > > > SeaBIOS to recognize those special tables and modify them. > > > > > > True, that's simple enough. My worry is we can add more such tables. > > > For example, we can decide to switch to XSDT in the future. > > > > I know of the following quirks that would have to be handled: > > > > 1 - the RSDP must be in the f-segment (where as all other tables can > > go into "high" memory). > > > > 2 - the RSDP has a checksum in a different location from the other > > tables and (with an XSDT) it can have two checksums. > > > > 3 - the RSDP has a pointer to the RSDT (and to the XSDT if present). > > > > 4 - the RSDT (and XSDT if present) has pointers to all the other > > tables (except RSDP, RSDT, DSDT, and FACS). The FADT pointer must be > > first in the list. > > > > 5 - the FADT table has pointers to DSDT and FACS. > > > > 6 - the FACS table must be 64 byte aligned. > > > > So, will a generic scheme really be able to handle all of the above > > quirks, or will we just be mixing some hardcoded quirks with some > > generic quirks? And, will the code to handle the above quirks in a > > generic fashion be of a higher complexity than simply hard-coding it? > > > > -Kevin > > --> > > So here's an implementation for align and FSEG. > Not a big deal as you see. > > I really have doubts about it however: BIOS still must be able to parse > get the resume vector in FACS in order to support wakeup, right? So this > means that we need to be able to parse RSDP and FACT. These happen to > be the only things that need anything not addressed by ADD and SUB so > ... maybe a couple of hardcoded quirks just to allocate these correctly > is cleaner.
Heh, it's actually pretty easy: let's just ask qemu to give us the address of the resume vector in a file with a pre-defined name. Linker can patch table offset there in the regular way. > Signed-off-by: Michael S. Tsirkin <m...@redhat.com> > > --- > > diff --git a/src/linker.c b/src/linker.c > index a1f473d..22a0dff 100644 > --- a/src/linker.c > +++ b/src/linker.c > @@ -34,7 +34,9 @@ void linker_link(const char *name) > if (entry->shift > 63) > continue; > if (entry->type != LINKER_ENTRY_TYPE_ADD && > - entry->type != LINKER_ENTRY_TYPE_SUB) > + entry->type != LINKER_ENTRY_TYPE_SUB && > + entry->type != LINKER_ENTRY_TYPE_ALIGN && > + entry->type != LINKER_ENTRY_TYPE_FSEG) > continue; > if (entry->format != LINKER_ENTRY_FORMAT_LE) > continue; > @@ -44,17 +46,55 @@ void linker_link(const char *name) > continue; > } > lsrc = strlen(entry->src_dst); > - if (!lsrc || lsrc + 1 + sizeof *entry >= entry->size) { > + if (!lsrc) { > warn_internalerror(); > continue; > } > src = romfile_find(entry->src_dst); > + if (!src) { > + warn_internalerror(); > + continue; > + } > + if (!src->data) { > + warn_internalerror(); > + continue; > + } > + if (entry->type == LINKER_ENTRY_TYPE_ALIGN || > + entry->type == LINKER_ENTRY_TYPE_FSEG) { > + void *data; > + u32 align; > + struct zone_s *zone; > + > + if (entry->shift > 31) { > + warn_internalerror(); > + continue; > + } > + align = 0x1 << entry->shift; > + if (align < MALLOC_MIN_ALIGN) > + align = MALLOC_MIN_ALIGN; > + zone = entry->type == LINKER_ENTRY_TYPE_FSEG ? > + &ZoneFSeg : &ZoneHigh; > + data = pmm_malloc(zone, PMM_DEFAULT_HANDLE, src->size, align); > + if (!data) { > + warn_internalerror(); > + continue; > + } > + memcpy(data, src->data, src->size); > + free(src->data); > + src->data = data; > + continue; > + } > + > + if (lsrc + 1 + sizeof *entry >= entry->size) { > + warn_internalerror(); > + continue; > + } > dst = romfile_find(entry->src_dst + lsrc + 1); > - if (!src || !dst) { > + if (!dst) { > warn_internalerror(); > continue; > } > - if (!src->data || !dst->data) { > + if (!dst->data) { > warn_internalerror(); > continue; > } > diff --git a/src/linker.h b/src/linker.h > index 2bb376d..b0cc536 100644 > --- a/src/linker.h > +++ b/src/linker.h > @@ -17,9 +17,12 @@ struct linker_entry_s { > char src_dst[]; > } PACKED; > > +/* Note: align types must appear before all other types. */ > enum linker_entry_type { > LINKER_ENTRY_TYPE_ADD = 0x0, > LINKER_ENTRY_TYPE_SUB = 0x1, > + LINKER_ENTRY_TYPE_ALIGN = 0x2, /* Align source to shift bits. Must come > first. */ > + LINKER_ENTRY_TYPE_FSEG = 0x3, /* Align source to shift bits in FSEG > memory. */ > }; > > enum linker_entry_format { _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios