Re: [SeaBIOS] How much RAM is required?
"Kevin O'Connor" writes: > On Fri, Aug 10, 2012 at 04:54:06PM +0200, Markus Armbruster wrote: >> Peter Stuge writes: >> > Markus Armbruster wrote: >> >> Could SeaBIOS fail more cleanly when it detects insufficient RAM? >> > >> > What would you propose? >> >> Fail POST with panic("Not enough RAM")? > > The amount of memory is communicated from QEMU to SeaBIOS via nvram > variables. As far as I know, those variables can only communicate ram > sizes in 1meg chunks - so there is no way to communicate (and/or > detect) a ramsize of under 1 meg. Not true, the variables *can* communicate more. Here's what QEMU stores in the RTC's NVRAM ("CMOS memory") on RAM: addr size meaning [unit] 0x15 2 base memory (below 1MiB) [KiB] 0x17 2 extended memory (between 1MiB and 64MiB) [KiB] 0x30 2 copy of 0x17/0x18 0x34 2 memory between 16MiB and 4GiB [64KiB] 0x5b 3 memory above 4GiB [64KiB] Thus, memory sizes up to 16MiB can be declared with 1KiB granularity, and up to 1TiB with 64KiB granularity. Note that RAM 0xa..0xf is inaccessible. However, the values QEMU *currently* stores are buggy for RAM sizes under 640KiB: base memory is set to 640KiB, and extended memory underflows. Code is pc_cmos_init() in hw/pc.c. I'll try to get that fixed, either by storing correct values, or by enforcing a 1MiB minimum. Here's how SeaBIOS uses this information, in ram_probe(): 1. read memory above 16MiB from 0x34/0x35. 2. if non-zero, add 16MiB, else read memory between 1MiB and 64MiB from 0x30/0x31, add 1MiB 3. read memory above 4GiB SeaBIOS doesn't read 0x15/0x16 at all. However, this SeaBIOS shortcoming is currently masked by the QEMU bug. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH] tsc: use kvmclock for calibration
Hi, > Isnt pmtimer ioport usable? 14MHz. Can give it a try. 14 MHz looks wrong though, apci.h says: /* PM Timer ticks per second (HZ) */ #define PM_TIMER_FREQUENCY 3579545 Is this fixed? Or hardware specific? cheers, Gerd ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH] tsc: use kvmclock for calibration
On Mon, Aug 13, 2012 at 12:37:11PM +0200, Gerd Hoffmann wrote: > Hi, > > > Isnt pmtimer ioport usable? 14MHz. > > Can give it a try. 14 MHz looks wrong though, apci.h says: > > /* PM Timer ticks per second (HZ) */ > #define PM_TIMER_FREQUENCY 3579545 > > Is this fixed? Or hardware specific? > 3.579545 MHz clock required by ACPI spec. -- Gleb. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH] add acpi pmtimer support
This patch makes seabios use the acpi pmtimer instead of tsc for timekeeping. The pmtimer has a fixed frequency and doesn't need calibration, thus it doesn't suffer from calibration errors due to a loaded host machine. Signed-off-by: Gerd Hoffmann --- src/clock.c | 29 + src/pciinit.c |5 + src/util.h|1 + 3 files changed, 35 insertions(+), 0 deletions(-) diff --git a/src/clock.c b/src/clock.c index 69e9f17..59f269b 100644 --- a/src/clock.c +++ b/src/clock.c @@ -129,11 +129,40 @@ emulate_tsc(void) return ret; } +u16 pmtimer_ioport VAR16VISIBLE; +u32 pmtimer_wraps VARLOW; +u32 pmtimer_last VARLOW; + +void pmtimer_init(u16 ioport, u32 khz) +{ +dprintf(1, "Using pmtimer, ioport 0x%x, freq %d kHz\n", ioport, khz); +SET_GLOBAL(pmtimer_ioport, ioport); +SET_GLOBAL(cpu_khz, khz); +} + +static u64 pmtimer_get(void) +{ +u16 ioport = GET_GLOBAL(pmtimer_ioport); +u32 wraps = GET_LOW(pmtimer_wraps); +u32 pmtimer = inl(ioport); + +if (pmtimer < GET_LOW(pmtimer_last)) { +wraps++; +SET_LOW(pmtimer_wraps, wraps); +} +SET_LOW(pmtimer_last, pmtimer); + +dprintf(9, "pmtimer: %u:%u\n", wraps, pmtimer); +return (u64)wraps << 24 | pmtimer; +} + static u64 get_tsc(void) { if (unlikely(GET_GLOBAL(no_tsc))) return emulate_tsc(); +if (GET_GLOBAL(pmtimer_ioport)) +return pmtimer_get(); return rdtscll(); } diff --git a/src/pciinit.c b/src/pciinit.c index 68f302a..31115ee 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -180,6 +180,9 @@ static const struct pci_device_id pci_class_tbl[] = { PCI_DEVICE_END, }; +/* PM Timer ticks per second (HZ) */ +#define PM_TIMER_FREQUENCY 3579545 + /* PIIX4 Power Management device (for ACPI) */ static void piix4_pm_init(struct pci_device *pci, void *arg) { @@ -191,6 +194,8 @@ static void piix4_pm_init(struct pci_device *pci, void *arg) pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */ pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ + +pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); } static const struct pci_device_id pci_device_tbl[] = { diff --git a/src/util.h b/src/util.h index 89e928c..1603a57 100644 --- a/src/util.h +++ b/src/util.h @@ -312,6 +312,7 @@ void lpt_setup(void); // clock.c #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer +void pmtimer_init(u16 ioport, u32 khz); int check_tsc(u64 end); void timer_setup(void); void ndelay(u32 count); -- 1.7.1 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH] tsc: use kvmclock for calibration
Add a comment about it in the source code. -#define PM_TIMER_FREQUENCY 3579545 +#define PM_TIMER_FREQUENCY 3579545 // 3.579545 MHz clock required by ACPI spec. On Mon, Aug 13, 2012 at 12:46 PM, Gleb Natapov wrote: > On Mon, Aug 13, 2012 at 12:37:11PM +0200, Gerd Hoffmann wrote: >> Hi, >> >> > Isnt pmtimer ioport usable? 14MHz. >> >> Can give it a try. 14 MHz looks wrong though, apci.h says: >> >> /* PM Timer ticks per second (HZ) */ >> #define PM_TIMER_FREQUENCY 3579545 >> >> Is this fixed? Or hardware specific? >> > 3.579545 MHz clock required by ACPI spec. > > -- > Gleb. > > ___ > SeaBIOS mailing list > SeaBIOS@seabios.org > http://www.seabios.org/mailman/listinfo/seabios ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH v2 0/2] Add IPMI SMBIOS/ACPI support
On Mon, Aug 13, 2012 at 09:47:50AM -0500, Corey Minyard wrote: > On 08/13/2012 01:25 AM, Gleb Natapov wrote: > >On Sun, Aug 12, 2012 at 08:22:12PM -0500, Corey Minyard wrote: > >>>Patch 2 is complex and I don't fully understand what it is doing. A > >>>quick scan leads me to believe it is constructing a dynamic SSDT - > >>>though it's not clear why a dynamic SSDT is needed and why the > >>>existing mechanism (see build_ssdt()) for generating dynamic SSDTs is > >>>not used. > >>It is constructing an addition to the DSDT table that is tacked on > >>to the end of that table if IPMI is present. It is complex, but > >>building ACPI namespace data is complex, and the data is not fixed > >>length. > >> > >You do not need to construct IPMI device dynamically in DSDT. Write it > >in AML and have _STA method that tells OSPM if device is present or not. > > There are lots of different options for IPMI devices. There are > three different interface types, with two string lengths. They can > all appear at arbitrary places in I/O or memory space. They can > have an interrupt or not. I would like to be able to represent all > off the possibilities so users can simulate any arbitrary machine > they want. > > I considered writing it in AML 8 times and figuring the offsets to > set the various values, but that seems rather messy to me. > How different are they. Can you give human readable example? > If the real desire is to have a single IPMI device type at a single > address with a single interrupt always on, we could do that. The > BIOS would still need a way to know that the device was present or > not, so something will have to be passed. I'm not sure that reading > from the standard address to detect the device is reliable enough, > but that could be done, too. > > -corey -- Gleb. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH v2 0/2] Add IPMI SMBIOS/ACPI support
On 08/13/2012 01:25 AM, Gleb Natapov wrote: On Sun, Aug 12, 2012 at 08:22:12PM -0500, Corey Minyard wrote: Patch 2 is complex and I don't fully understand what it is doing. A quick scan leads me to believe it is constructing a dynamic SSDT - though it's not clear why a dynamic SSDT is needed and why the existing mechanism (see build_ssdt()) for generating dynamic SSDTs is not used. It is constructing an addition to the DSDT table that is tacked on to the end of that table if IPMI is present. It is complex, but building ACPI namespace data is complex, and the data is not fixed length. You do not need to construct IPMI device dynamically in DSDT. Write it in AML and have _STA method that tells OSPM if device is present or not. There are lots of different options for IPMI devices. There are three different interface types, with two string lengths. They can all appear at arbitrary places in I/O or memory space. They can have an interrupt or not. I would like to be able to represent all off the possibilities so users can simulate any arbitrary machine they want. I considered writing it in AML 8 times and figuring the offsets to set the various values, but that seems rather messy to me. If the real desire is to have a single IPMI device type at a single address with a single interrupt always on, we could do that. The BIOS would still need a way to know that the device was present or not, so something will have to be passed. I'm not sure that reading from the standard address to detect the device is reliable enough, but that could be done, too. -corey ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH v2 0/2] Add IPMI SMBIOS/ACPI support
On 08/13/2012 10:15 AM, Gleb Natapov wrote: On Mon, Aug 13, 2012 at 09:47:50AM -0500, Corey Minyard wrote: On 08/13/2012 01:25 AM, Gleb Natapov wrote: On Sun, Aug 12, 2012 at 08:22:12PM -0500, Corey Minyard wrote: Patch 2 is complex and I don't fully understand what it is doing. A quick scan leads me to believe it is constructing a dynamic SSDT - though it's not clear why a dynamic SSDT is needed and why the existing mechanism (see build_ssdt()) for generating dynamic SSDTs is not used. It is constructing an addition to the DSDT table that is tacked on to the end of that table if IPMI is present. It is complex, but building ACPI namespace data is complex, and the data is not fixed length. You do not need to construct IPMI device dynamically in DSDT. Write it in AML and have _STA method that tells OSPM if device is present or not. There are lots of different options for IPMI devices. There are three different interface types, with two string lengths. They can all appear at arbitrary places in I/O or memory space. They can have an interrupt or not. I would like to be able to represent all off the possibilities so users can simulate any arbitrary machine they want. I considered writing it in AML 8 times and figuring the offsets to set the various values, but that seems rather messy to me. How different are they. Can you give human readable example? Here are the examples from the IPMI spec. I lied a little bit, there are actually four standard interfaces (one can be on an SMBus), but it's a different thing to manage, I think. -corey Device(MI0) { Name(_HID, EISAID("IPI0001")) Name(_STR, Unicode("IPMI_SMIC")) Name(_UID, 0) // UID for the primary IPMI system interface in the system Name(_CRS, ResourceTemplate() { IO(Decode16, 0xCA9, 0, 3) // Ports 0xCA9, 0xCAA & 0xCAB } ) Method(_IFT) { Return(0x02) // IPMI SMIC } Method(_SRV) { Return(0x0100) // IPMI Specification Revision 1.0 } //This interface does not support interrupt } Device(MI0) { Name(_HID, EISAID("IPI0001")) Name(_STR, Unicode("IPMI_KCS")) Name(_UID, 0) Name(_CRS, ResourceTemplate() { QWordMemory( ResourceConsumer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0x, // _GRA, Address granularity. 0x8C020CA2, // _MIN, Address range minimum 0x8C020CA4, // _MAX, Address range max 0x, // _TRA, Translation. 0x0002, // _LEN, Address range length , // Resource Source Index , // Resource Source Name , // A name to refer back to this resource , // _MTP, Nothing=>AddressRangeMemory , // _TTP, Translation. Nothing=>TypeStatic ) } ) Method(_IFT) { Return(0x01) // IPMI KCS } Method(_SRV) { Return(0x0100) // IPMI Specification Revision 1.0 } // This interface does not support interrupt } Device(MI0) { Name(_HID, EISAID("IPI0001")) Name(_STR, Unicode("IPMI_BT")) Name(_UID, 0) Name(_CRS, ResourceTemplate() { IO(Decode16, 0x0E4, 0, 3) // Ports 0xE4h:E6h Interrupt(ResourceProducer,...){20} // GSI is 20 } ) // Returns the interface type Method(_IFT) { Return(0x03) // IPMI BT } // Returns the interface specification revision Method(_SRV) { Return(0x0150) // IPMI Specification Revision 1.5 } } Device (SMB0) // example SMBus host controller { Name(_HID, "") // Vendor-Specific HID Name(_UID, 0) // Unique ID of particular host controller : : Device (SSIF) { Name(_HID,"IPI0001") // IPMI system interface Name(_UID, 0) // Unique device identifier Name(_STR, Unicode("IPMI_SSIF")) // Returns the interface type Method _IFT { Return(0x04) } // Returns the SSIF slave address Method _ADR { Return(0x10) } Method(_SRV) { Return(0x0200) // IPMI Specification Version 2.0 } } // end Device SSIF } // end Device SMB0 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH] add acpi pmtimer support
On Mon, Aug 13, 2012 at 03:04:10PM +0200, Gerd Hoffmann wrote: > This patch makes seabios use the acpi pmtimer instead of tsc for > timekeeping. The pmtimer has a fixed frequency and doesn't need > calibration, thus it doesn't suffer from calibration errors due to a > loaded host machine. It looks okay to me. It'd be nice to have a CONFIG_PMTIMER for it, but it can be added on top. -Kevin ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH] add acpi pmtimer support\
On Mon, Aug 13, 2012 at 03:04:10PM +0200, Gerd Hoffmann wrote: > This patch makes seabios use the acpi pmtimer instead of tsc for > timekeeping. The pmtimer has a fixed frequency and doesn't need > calibration, thus it doesn't suffer from calibration errors due to a > loaded host machine. > > Signed-off-by: Gerd Hoffmann > --- > src/clock.c | 29 + > src/pciinit.c |5 + > src/util.h|1 + > 3 files changed, 35 insertions(+), 0 deletions(-) > > diff --git a/src/clock.c b/src/clock.c > index 69e9f17..59f269b 100644 > --- a/src/clock.c > +++ b/src/clock.c > @@ -129,11 +129,40 @@ emulate_tsc(void) > return ret; > } > > +u16 pmtimer_ioport VAR16VISIBLE; > +u32 pmtimer_wraps VARLOW; > +u32 pmtimer_last VARLOW; > + > +void pmtimer_init(u16 ioport, u32 khz) > +{ > +dprintf(1, "Using pmtimer, ioport 0x%x, freq %d kHz\n", ioport, khz); > +SET_GLOBAL(pmtimer_ioport, ioport); > +SET_GLOBAL(cpu_khz, khz); > +} > + > +static u64 pmtimer_get(void) > +{ > +u16 ioport = GET_GLOBAL(pmtimer_ioport); > +u32 wraps = GET_LOW(pmtimer_wraps); > +u32 pmtimer = inl(ioport); > + > +if (pmtimer < GET_LOW(pmtimer_last)) { > +wraps++; > +SET_LOW(pmtimer_wraps, wraps); > +} > +SET_LOW(pmtimer_last, pmtimer); > + > +dprintf(9, "pmtimer: %u:%u\n", wraps, pmtimer); > +return (u64)wraps << 24 | pmtimer; > +} > + > static u64 > get_tsc(void) > { > if (unlikely(GET_GLOBAL(no_tsc))) > return emulate_tsc(); > +if (GET_GLOBAL(pmtimer_ioport)) > +return pmtimer_get(); > return rdtscll(); > } > > diff --git a/src/pciinit.c b/src/pciinit.c > index 68f302a..31115ee 100644 > --- a/src/pciinit.c > +++ b/src/pciinit.c > @@ -180,6 +180,9 @@ static const struct pci_device_id pci_class_tbl[] = { > PCI_DEVICE_END, > }; > > +/* PM Timer ticks per second (HZ) */ > +#define PM_TIMER_FREQUENCY 3579545 > + > /* PIIX4 Power Management device (for ACPI) */ > static void piix4_pm_init(struct pci_device *pci, void *arg) > { > @@ -191,6 +194,8 @@ static void piix4_pm_init(struct pci_device *pci, void > *arg) > pci_config_writeb(bdf, 0x80, 0x01); /* enable PM io space */ > pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); > pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */ > + > +pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); > } > > static const struct pci_device_id pci_device_tbl[] = { > diff --git a/src/util.h b/src/util.h > index 89e928c..1603a57 100644 > --- a/src/util.h > +++ b/src/util.h > @@ -312,6 +312,7 @@ void lpt_setup(void); > // clock.c > #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT > #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer > +void pmtimer_init(u16 ioport, u32 khz); > int check_tsc(u64 end); > void timer_setup(void); > void ndelay(u32 count); Looks good. ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH v2 0/2] Add IPMI SMBIOS/ACPI support
On Mon, Aug 13, 2012 at 02:30:52PM -0500, Corey Minyard wrote: > On 08/13/2012 10:15 AM, Gleb Natapov wrote: > >On Mon, Aug 13, 2012 at 09:47:50AM -0500, Corey Minyard wrote: > >>On 08/13/2012 01:25 AM, Gleb Natapov wrote: > >>>On Sun, Aug 12, 2012 at 08:22:12PM -0500, Corey Minyard wrote: > >Patch 2 is complex and I don't fully understand what it is doing. A > >quick scan leads me to believe it is constructing a dynamic SSDT - > >though it's not clear why a dynamic SSDT is needed and why the > >existing mechanism (see build_ssdt()) for generating dynamic SSDTs is > >not used. > It is constructing an addition to the DSDT table that is tacked on > to the end of that table if IPMI is present. It is complex, but > building ACPI namespace data is complex, and the data is not fixed > length. > > >>>You do not need to construct IPMI device dynamically in DSDT. Write it > >>>in AML and have _STA method that tells OSPM if device is present or not. > >>There are lots of different options for IPMI devices. There are > >>three different interface types, with two string lengths. They can > >>all appear at arbitrary places in I/O or memory space. They can > >>have an interrupt or not. I would like to be able to represent all > >>off the possibilities so users can simulate any arbitrary machine > >>they want. > >> > >>I considered writing it in AML 8 times and figuring the offsets to > >>set the various values, but that seems rather messy to me. > >> > >How different are they. Can you give human readable example? > > Here are the examples from the IPMI spec. I lied a little bit, > there are actually four standard interfaces (one can be on an > SMBus), but it's a different thing to manage, I think. Does your patch produce all of the four variants you've identified? What fields (if any) are dynamic within the variants? -Kevin ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios