Index: trunk/CHANGES =================================================================== --- trunk/CHANGES (revision 83) +++ trunk/CHANGES (revision 84) @@ -1,3 +1,8 @@ +- Factorized code to prepare a dynamic memory detection algorithm ... +- Optimized smbios table address search +- Optimized cursor spinout in textmode if no verbose mode is set +- Added ram table structures definitions +- Added getSmbios() a param permitting to select between orig and new smbios entries - Changed "Default Partition" behaviour to accept only native system volumes or foreign partitions. - Added NVIDIA new NVCAP customization support and support for ION gfx cards from aserebln - Added ATI new framebuffers support and new cards from PCEFI10.6 Index: trunk/i386/libsaio/SMBIOS.h =================================================================== --- trunk/i386/libsaio/SMBIOS.h (revision 83) +++ trunk/i386/libsaio/SMBIOS.h (revision 84) @@ -23,7 +23,6 @@ /* This file is a stripped-down version of the one found in the AppleSMBIOS project. * Changes: * - Don't use pragma pack but instead use GCC's packed attribute - * - Remove everything except the entry point structure. We don't need anything else. */ #ifndef _LIBSAIO_SMBIOS_H @@ -33,37 +32,86 @@ * Based on System Management BIOS Reference Specification v2.5 */ -typedef UInt8 SMBString; -typedef UInt8 SMBByte; -typedef UInt16 SMBWord; -typedef UInt32 SMBDWord; -typedef UInt64 SMBQWord; +typedef uint8_t SMBString; +typedef uint8_t SMBByte; +typedef uint16_t SMBWord; +typedef uint32_t SMBDWord; +typedef uint64_t SMBQWord; -struct DMIHeader{ - SMBByte type; - SMBByte length; - SMBWord handle; +struct DMIHeader { + SMBByte type; + SMBByte length; + SMBWord handle; } __attribute__((packed)); struct DMIEntryPoint { - SMBByte anchor[5]; - SMBByte checksum; - SMBWord tableLength; - SMBDWord tableAddress; - SMBWord structureCount; - SMBByte bcdRevision; + SMBByte anchor[5]; + SMBByte checksum; + SMBWord tableLength; + SMBDWord tableAddress; + SMBWord structureCount; + SMBByte bcdRevision; } __attribute__((packed)); struct SMBEntryPoint { - SMBByte anchor[4]; - SMBByte checksum; - SMBByte entryPointLength; - SMBByte majorVersion; - SMBByte minorVersion; - SMBWord maxStructureSize; - SMBByte entryPointRevision; - SMBByte formattedArea[5]; - struct DMIEntryPoint dmi; + SMBByte anchor[4]; + SMBByte checksum; + SMBByte entryPointLength; + SMBByte majorVersion; + SMBByte minorVersion; + SMBWord maxStructureSize; + SMBByte entryPointRevision; + SMBByte formattedArea[5]; + struct DMIEntryPoint dmi; } __attribute__((packed)); +struct DMIMemoryControllerInfo {/* 3.3.6 Memory Controller Information (Type 5) */ + struct DMIHeader dmiHeader; + SMBByte errorDetectingMethod; + SMBByte errorCorrectingCapability; + SMBByte supportedInterleave; + SMBByte currentInterleave; + SMBByte maxMemoryModuleSize; + SMBWord supportedSpeeds; + SMBWord supportedMemoryTypes; + SMBByte memoryModuleVoltage; + SMBByte numberOfMemorySlots; +} __attribute__((packed)); + +struct DMIMemoryModuleInfo { /* 3.3.7 Memory Module Information (Type 6) */ + struct DMIHeader dmiHeader; + SMBByte socketDesignation; + SMBByte bankConnections; + SMBByte currentSpeed; + SMBWord currentMemoryType; + SMBByte installedSize; + SMBByte enabledSize; + SMBByte errorStatus; +} __attribute__((packed)); + +struct DMIPhysicalMemoryArray { /* 3.3.17 Physical Memory Array (Type 16) */ + struct DMIHeader dmiHeader; + SMBByte location; + SMBByte use; + SMBByte memoryCorrectionError; + SMBDWord maximumCapacity; + SMBWord memoryErrorInformationHandle; + SMBWord numberOfMemoryDevices; +} __attribute__((packed)); + +struct DMIMemoryDevice { /* 3.3.18 Memory Device (Type 17) */ + struct DMIHeader dmiHeader; + SMBWord physicalMemoryArrayHandle; + SMBWord memoryErrorInformationHandle; + SMBWord totalWidth; + SMBWord dataWidth; + SMBWord size; + SMBByte formFactor; + SMBByte deviceSet; + SMBByte deviceLocator; + SMBByte bankLocator; + SMBByte memoryType; + SMBWord typeDetail; +} __attribute__((packed)); + #endif /* !_LIBSAIO_SMBIOS_H */ Index: trunk/i386/libsaio/smbios_patcher.c =================================================================== --- trunk/i386/libsaio/smbios_patcher.c (revision 83) +++ trunk/i386/libsaio/smbios_patcher.c (revision 84) @@ -13,7 +13,7 @@ #include "SMBIOS.h" #ifndef DEBUG_SMBIOS -#define DEBUG_SMBIOS 0 +#define DEBUG_SMBIOS 1 #endif #if DEBUG_SMBIOS @@ -154,11 +154,14 @@ static int sm_get_memtype (char *name, int table_num) { - if (table_num < MAX_RAM_SLOTS && - Platform.RAM.DIMM[table_num].InUse && - Platform.RAM.DIMM[table_num].Type != 0) - { - return Platform.RAM.DIMM[table_num].Type; + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform.DMI.DIMM[table_num]; + if (Platform.RAM.DIMM[map].InUse && Platform.RAM.DIMM[map].Type != 0) { + DBG("RAM Detected Type = %d\n", Platform.RAM.DIMM[map].Type); + return Platform.RAM.DIMM[map].Type; + } } return SMB_MEM_TYPE_DDR2; } @@ -166,43 +169,50 @@ static int sm_get_memspeed (char *name, int table_num) { if (Platform.RAM.Frequency != 0) { - return Platform.RAM.Frequency/1000000; + DBG("RAM Detected Freq = %d\n", Platform.RAM.Frequency/1000000); + return Platform.RAM.Frequency/1000000; } - return 667; + return 800; } static char *sm_get_memvendor (char *name, int table_num) { - if (table_num < MAX_RAM_SLOTS && - Platform.RAM.DIMM[table_num].InUse && - strlen(Platform.RAM.DIMM[table_num].Vendor) > 0) - { - DBG("Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].Vendor); - return Platform.RAM.DIMM[table_num].Vendor; + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform.DMI.DIMM[table_num]; + if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].Vendor) > 0) { + DBG("RAM Detected Vendor[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].Vendor); + return Platform.RAM.DIMM[map].Vendor; + } } return "N/A"; } static char *sm_get_memserial (char *name, int table_num) { - if (table_num < MAX_RAM_SLOTS && - Platform.RAM.DIMM[table_num].InUse && - strlen(Platform.RAM.DIMM[table_num].SerialNo) > 0) - { - DBG("SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].SerialNo); - return Platform.RAM.DIMM[table_num].SerialNo; + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform.DMI.DIMM[table_num]; + if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].SerialNo) > 0) { + DBG("RAM Detected SerialNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].SerialNo); + return Platform.RAM.DIMM[map].SerialNo; + } } return "N/A"; } static char *sm_get_mempartno (char *name, int table_num) { - if (table_num < MAX_RAM_SLOTS && - Platform.RAM.DIMM[table_num].InUse && - strlen(Platform.RAM.DIMM[table_num].PartNo) > 0) - { - DBG("PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[table_num].PartNo); - return Platform.RAM.DIMM[table_num].PartNo; + int map; + + if (table_num < MAX_RAM_SLOTS) { + map = Platform.DMI.DIMM[table_num]; + if (Platform.RAM.DIMM[map].InUse && strlen(Platform.RAM.DIMM[map].PartNo) > 0) { + DBG("Ram Detected PartNo[%d]='%s'\n", table_num, Platform.RAM.DIMM[map].PartNo); + return Platform.RAM.DIMM[map].PartNo; + } } return "N/A"; } @@ -249,36 +259,31 @@ {.type=132, .len=0x06, .numfunc=sm_one} }; -struct SMBEntryPoint *getAddressOfSmbiosTable(void) +// getting smbios addr with fast compare ops, late checksum testing ... +#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) ) +static const char * const SMTAG = "_SM_"; +static const char* const DMITAG= "_DMI_"; + +static struct SMBEntryPoint *getAddressOfSmbiosTable(void) { - /* First see if we can even find the damn SMBIOS table - * The logic here is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking + struct SMBEntryPoint *smbios; + + /* + * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_"). */ - void *smbios_addr = (void*)SMBIOS_RANGE_START; - - for (; (smbios_addr<=(void*)SMBIOS_RANGE_END) && (*(uint32_t*)smbios_addr!=SMBIOS_ANCHOR_UINT32_LE); smbios_addr+=16) ; - if (smbios_addr <= (void*)SMBIOS_RANGE_END) { - /* NOTE: The specification does not specifically state what to do in the event of finding an - * SMBIOS anchor on an invalid table. It might be better to move this code into the for loop - * so that searching can continue. - */ - uint8_t csum = checksum8(smbios_addr, sizeof(struct SMBEntryPoint)); - /* The table already contains the checksum so we merely need to see if its checksum is now zero. */ - if (csum != 0) { - printf("Found SMBIOS anchor but bad table checksum. Assuming no SMBIOS.\n"); - sleep(5); - smbios_addr = 0; + smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START; + while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) { + if (COMPARE_DWORD(smbios->anchor, SMTAG) && COMPARE_DWORD(smbios->dmi.anchor, DMITAG) && + checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0) + { + return smbios; } - } else { - /* If this happens, it's possible that a PnP BIOS call can be done to retrieve the address of the table. - * The latest versions of the spec state that modern programs should not even attempt to do this. - */ - printf("Unable to find SMBIOS table.\n"); - sleep(5); - smbios_addr = 0; + smbios = (((void*) smbios) + 16); } - return smbios_addr; + printf("ERROR: Unable to find SMBIOS!\n"); + sleep(5); + return NULL; } /* Compute necessary space requirements for new smbios */ @@ -690,13 +695,68 @@ verbose("Patched DMI Table\n"); } -struct SMBEntryPoint *getSmbios(void) +struct SMBEntryPoint *getSmbios(int which) { - struct SMBEntryPoint *orig_address; - struct SMBEntryPoint *new_address; + static struct SMBEntryPoint *orig = NULL; // cached + static struct SMBEntryPoint *patched = NULL; // cached - orig_address=getAddressOfSmbiosTable(); - new_address = smbios_dry_run(orig_address); - smbios_real_run(orig_address, new_address); - return new_address; + if (orig == NULL) orig = getAddressOfSmbiosTable(); + + switch (which) { + case SMBIOS_ORIGINAL: + return orig; + case SMBIOS_PATCHED: + if (patched == NULL) { + patched = smbios_dry_run(orig); + smbios_real_run(orig, patched); + } + return patched; + default: + printf("ERROR: invalid option for getSmbios() !!\n"); + return NULL; + } } + +/** + * Get a table structure entry from a type specification and a smbios address + * return NULL if table is not found + */ +struct DMIHeader *getSmbiosTableStructure(struct SMBEntryPoint *smbios, int type, int min_length) +{ + struct DMIHeader * dmihdr=NULL; + bool found = false; + SMBByte* p; + int i; + + if (smbios == NULL || type < 0 ) return NULL; +#if DEBUG_SMBIOS + printf(">>> SMBIOSAddr=0x%08x\n", smbios); + printf(">>> DMI: addr=0x%08x, len=0x%d, count=%d\n", smbios->dmi.tableAddress, + smbios->dmi.tableLength, smbios->dmi.structureCount); +#endif + p = (SMBByte *) smbios->dmi.tableAddress; + for (i=0; i < smbios->dmi.structureCount && p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength; i++) + { + dmihdr = (struct DMIHeader *) p; +#if DEBUG_SMBIOS + verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length); +#endif + if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break; + if (dmihdr->type == type) /* 3.3.2 System Information */ + { + if (dmihdr->length >= min_length) found = true; + break; + } + p = p + dmihdr->length; + while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) + { + p++; + } + p += 2; + } + +#if DEBUG_SMBIOS + printf("DMI header found for table type %d, length = %d\n", type, dmihdr->type, dmihdr->length); +#endif + return found ? dmihdr : NULL; + } Index: trunk/i386/libsaio/smbios_patcher.h =================================================================== --- trunk/i386/libsaio/smbios_patcher.h (revision 83) +++ trunk/i386/libsaio/smbios_patcher.h (revision 84) @@ -1,6 +1,9 @@ /* * Copyright 2008 mackerintel */ +/* + * AsereBLN: cleanup + */ #ifndef __LIBSAIO_SMBIOS_PATCHER_H #define __LIBSAIO_SMBIOS_PATCHER_H @@ -8,53 +11,44 @@ #include "libsaio.h" #include "SMBIOS.h" -extern EFI_GUID gEfiAcpiTableGuid; -extern EFI_GUID gEfiAcpi20TableGuid; - /* From Foundation/Efi/Guid/Smbios/SmBios.h */ /* Modified to wrap Data4 array init with {} */ -#define EFI_SMBIOS_TABLE_GUID \ -{ \ -0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} \ -} +#define EFI_SMBIOS_TABLE_GUID {0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}} -/* From Foundation/Efi/Guid/Smbios/SmBios.c */ -//EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID; - #define SMBIOS_RANGE_START 0x000F0000 #define SMBIOS_RANGE_END 0x000FFFFF -/* '_SM_' in little endian: */ -#define SMBIOS_ANCHOR_UINT32_LE 0x5f4d535f +#define SMBIOS_ORIGINAL 0 +#define SMBIOS_PATCHED 1 struct smbios_table_header { - uint8_t type; - uint8_t length; - uint16_t handle; + uint8_t type; + uint8_t length; + uint16_t handle; } __attribute__ ((packed)); struct smbios_property { - char *name; - uint8_t table_type; + char *name; + uint8_t table_type; enum {SMSTRING, SMWORD, SMBYTE, SMOWORD} value_type; - int offset; - //union { - int (*auto_int) (char *name, int table_num); - char * (*auto_str) (char *name, int table_num); - char * (*auto_oword) (char *name, int table_num); - //}; + int offset; + int (*auto_int) (char *name, int table_num); + char *(*auto_str) (char *name, int table_num); + char *(*auto_oword) (char *name, int table_num); }; struct smbios_table_description { - uint8_t type; - int len; - int (*numfunc)(int tablen); + uint8_t type; + int len; + int (*numfunc)(int tablen); }; - -extern struct SMBEntryPoint * getAddressOfSmbiosTable(void); -extern struct SMBEntryPoint * getSmbios(void); +/** call with flag SMBIOS_ORIGINAL to get orig. entrypoint + or call with flag SMBIOS_PATCHED to get patched smbios entrypoint +*/ +extern struct DMIHeader *getSmbiosTableStructure(struct SMBEntryPoint *smbios, int type, int min_length); +extern struct SMBEntryPoint *getSmbios(int); #endif /* !__LIBSAIO_SMBIOS_PATCHER_H */ Index: trunk/i386/libsaio/pci_root.c =================================================================== --- trunk/i386/libsaio/pci_root.c (revision 83) +++ trunk/i386/libsaio/pci_root.c (revision 84) @@ -80,7 +80,7 @@ { verbose("No DSDT found, using 0 as uid value.\n"); rootuid = 0; - return rootuid; + goto out; } fsize = file_size(fd); Index: trunk/i386/libsaio/platform.h =================================================================== --- trunk/i386/libsaio/platform.h (revision 83) +++ trunk/i386/libsaio/platform.h (revision 84) @@ -1,5 +1,6 @@ /* * platform.h + * AsereBLN: reworked and extended * */ @@ -63,18 +64,21 @@ #define SMB_MEM_CHANNEL_TRIPLE 3 /* Maximum number of ram slots */ -#define MAX_RAM_SLOTS 8 +#define MAX_RAM_SLOTS 12 +#define RAM_SLOT_ENUMERATOR {0, 2, 4, 1, 3, 5, 6, 8, 10, 7, 9, 11} /* Maximum number of SPD bytes */ #define MAX_SPD_SIZE 256 +/* Size of SMBIOS UUID in bytes */ +#define UUID_LEN 16 + typedef struct _RamSlotInfo_t { bool InUse; uint8_t Type; char Vendor[64]; char PartNo[64]; char SerialNo[16]; - uint8_t spd[MAX_SPD_SIZE]; } RamSlotInfo_t; typedef struct _PlatformInfo_t { @@ -97,13 +101,19 @@ uint32_t BrandString[16]; // 48 Byte Branding String uint32_t CPUID[CPUID_MAX][4]; // CPUID 0..4, 80..81 Raw Values } CPU; + struct RAM { RamSlotInfo_t DIMM[MAX_RAM_SLOTS]; // Information about each slot uint64_t Frequency; // Ram Frequency } RAM; - uint8_t Type; // JrCs: System Type: 1=Desktop, 2=Portable... according ACPI2.0 (FADT: PM_Profile) - + struct DMI { + int MaxMemorySlots; // number of memory slots polulated by SMBIOS + int CntMemorySlots; // number of memory slots counted + int MemoryModules; // number of memory modules installed + int DIMM[MAX_RAM_SLOTS]; // Information and SPD mapping for each slot + } DMI; + uint8_t Type; // System Type: 1=Desktop, 2=Portable... according ACPI2.0 (FACP: PM_Profile) } PlatformInfo_t; extern PlatformInfo_t Platform; Index: trunk/i386/libsaio/fake_efi.c =================================================================== --- trunk/i386/libsaio/fake_efi.c (revision 83) +++ trunk/i386/libsaio/fake_efi.c (revision 84) @@ -18,7 +18,7 @@ #include "pci.h" #include "sl.h" -extern struct SMBEntryPoint * getSmbios(); +extern struct SMBEntryPoint * getSmbios(int which); // now cached extern void setup_pci_devs(pci_dt_t *pci_dt); /* @@ -284,13 +284,6 @@ * SMBIOS */ -/* From Foundation/Efi/Guid/Smbios/SmBios.h */ -/* Modified to wrap Data4 array init with {} */ -#define EFI_SMBIOS_TABLE_GUID \ - { \ - 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} \ - } - /* From Foundation/Efi/Guid/Smbios/SmBios.c */ EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID; @@ -346,52 +339,19 @@ return dst; } -#define DEBUG_SMBIOS 0 - /* Get the SystemID from the bios dmi info */ static EFI_CHAR8* getSmbiosUUID() { struct SMBEntryPoint *smbios; - struct DMIHeader *dmihdr; SMBByte *p; - int i, found, isZero, isOnes; + int i, isZero, isOnes; static EFI_CHAR8 uuid[UUID_LEN]; - smbios = getAddressOfSmbiosTable(); /* checks for _SM_ anchor and table header checksum */ - if (memcmp( &smbios->dmi.anchor[0], "_DMI_", 5) != 0) { - return 0; - } + smbios = getSmbios(SMBIOS_PATCHED); /* checks for _SM_ anchor and table header checksum */ + if (smbios==NULL) return 0; // getSmbios() return a non null value if smbios is found -#if DEBUG_SMBIOS - verbose(">>> SMBIOSAddr=0x%08x\n", smbios); - verbose(">>> DMI: addr=0x%08x, len=0x%d, count=%d\n", smbios->dmi.tableAddress, - smbios->dmi.tableLength, smbios->dmi.structureCount); -#endif - i = 0; - found = 0; - p = (SMBByte *) smbios->dmi.tableAddress; - while (i < smbios->dmi.structureCount && p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength) - { - dmihdr = (struct DMIHeader *) p; -#if DEBUG_SMBIOS - verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length); -#endif - if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break; - if (dmihdr->type == 1) /* 3.3.2 System Information */ - { - if (dmihdr->length >= 0x19) found = 1; - break; - } - p = p + dmihdr->length; - while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00)) - { - p++; - } - p += 2; - i++; - } - - if (!found) return 0; + p = (SMBByte *) getSmbiosTableStructure(smbios, 1, 0x19); /* Type 1: (3.3.2) System Information */ + if (p==NULL) return NULL; verbose("Found SMBIOS System Information Table 1\n"); p += 8; @@ -527,7 +487,7 @@ /* Installs all the needed configuration table entries */ void setupEfiConfigurationTable() { - smbios_p = (EFI_PTR32)getSmbios(); + smbios_p = (EFI_PTR32)getSmbios(SMBIOS_PATCHED); addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL); // Setup ACPI with DSDT overrides (mackerintel's patch) Index: trunk/i386/boot2/graphics.c =================================================================== --- trunk/i386/boot2/graphics.c (revision 83) +++ trunk/i386/boot2/graphics.c (revision 84) @@ -1172,7 +1172,6 @@ // Display and clear the activity indicator. static char indicator[] = {'-', '\\', '|', '/', '-', '\\', '|', '/', '\0'}; -#define kNumIndicators (sizeof(indicator) - 1) // To prevent a ridiculously fast-spinning indicator, // ensure a minimum of 1/9 sec between animation frames. @@ -1181,9 +1180,7 @@ void spinActivityIndicator(int sectors) { - static unsigned long lastTickTime = 0; - unsigned long currentTickTime = time18(); - static char string[3] = {'\0', '\b', '\0'}; + static unsigned long lastTickTime = 0, currentTickTime; if (previewTotalSectors && previewSaveunder) { @@ -1198,17 +1195,21 @@ return; } - if (currentTickTime < lastTickTime + MIN_TICKS) - return; - else - lastTickTime = currentTickTime; - - if ( getVideoMode() == VGA_TEXT_MODE ) - { - if (currentIndicator >= kNumIndicators) currentIndicator = 0; - string[0] = indicator[currentIndicator++]; - verbose(string); - } + if (gVerboseMode) { + currentTickTime = time18(); // late binding + if (currentTickTime < lastTickTime + MIN_TICKS) { + return; + } else { + lastTickTime = currentTickTime; + } + + if (getVideoMode() == VGA_TEXT_MODE) { + if (currentIndicator >= sizeof(indicator)) { + currentIndicator = 0; + } + printf("%c\b", indicator[currentIndicator++]); + } + } } void Index: trunk/i386/libsa/libsa.h =================================================================== --- trunk/i386/libsa/libsa.h (revision 83) +++ trunk/i386/libsa/libsa.h (revision 84) @@ -91,6 +91,7 @@ extern int strlen(const char * str); extern char * strcat(char * s1, const char * s2); extern char * strncat(char * s1, const char * s2, size_t n); +extern char * strdup(const char *s1); #if STRNCASECMP extern int strncasecmp(const char * s1, const char * s2, size_t n); Index: trunk/i386/libsa/printf.c =================================================================== --- trunk/i386/libsa/printf.c (revision 83) +++ trunk/i386/libsa/printf.c (revision 84) @@ -45,6 +45,7 @@ } /*VARARGS1*/ +/* now slprintf() return the length of the string as in man sprintf()*/ int sprintf(char * str, const char * fmt, ...) { va_list ap; @@ -56,7 +57,7 @@ prf(fmt, ap, sputc, &pi); *pi.str = '\0'; va_end(ap); - return 0; + return (pi.str - str); } /*VARARGS1*/ Index: trunk/i386/libsa/string.c =================================================================== --- trunk/i386/libsa/string.c (revision 83) +++ trunk/i386/libsa/string.c (revision 84) @@ -241,6 +241,11 @@ return(strncat(s1, s2, strlen(s2))); } +char *strdup(const char *s1) +{ + return strcpy(malloc(strlen(s1) + 1), s1); +} + #if STRNCASECMP int strncasecmp(const char *s1, const char *s2, size_t len) {