1 /* 2 * This file is part of the coreboot project. 3 * 4 * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA 18 */ 19 20 #include <common.h> 21 #include <asm/arch/timestamp.h> 22 #include <asm/arch/sysinfo.h> 23 #include <linux/compiler.h> 24 25 struct timestamp_entry { 26 uint32_t entry_id; 27 uint64_t entry_stamp; 28 } __packed; 29 30 struct timestamp_table { 31 uint64_t base_time; 32 uint32_t max_entries; 33 uint32_t num_entries; 34 struct timestamp_entry entries[0]; /* Variable number of entries */ 35 } __packed; 36 37 static struct timestamp_table *ts_table __attribute__((section(".data"))); 38 39 void timestamp_init(void) 40 { 41 ts_table = lib_sysinfo.tstamp_table; 42 #ifdef CONFIG_SYS_X86_TSC_TIMER 43 timer_set_base(ts_table->base_time); 44 #endif 45 timestamp_add_now(TS_U_BOOT_INITTED); 46 } 47 48 void timestamp_add(enum timestamp_id id, uint64_t ts_time) 49 { 50 struct timestamp_entry *tse; 51 52 if (!ts_table || (ts_table->num_entries == ts_table->max_entries)) 53 return; 54 55 tse = &ts_table->entries[ts_table->num_entries++]; 56 tse->entry_id = id; 57 tse->entry_stamp = ts_time - ts_table->base_time; 58 } 59 60 void timestamp_add_now(enum timestamp_id id) 61 { 62 timestamp_add(id, rdtsc()); 63 } 64 65 int timestamp_add_to_bootstage(void) 66 { 67 uint i; 68 69 if (!ts_table) 70 return -1; 71 72 for (i = 0; i < ts_table->num_entries; i++) { 73 struct timestamp_entry *tse = &ts_table->entries[i]; 74 const char *name = NULL; 75 76 switch (tse->entry_id) { 77 case TS_START_ROMSTAGE: 78 name = "start-romstage"; 79 break; 80 case TS_BEFORE_INITRAM: 81 name = "before-initram"; 82 break; 83 case TS_DEVICE_INITIALIZE: 84 name = "device-initialize"; 85 break; 86 case TS_DEVICE_DONE: 87 name = "device-done"; 88 break; 89 case TS_SELFBOOT_JUMP: 90 name = "selfboot-jump"; 91 break; 92 } 93 if (name) { 94 bootstage_add_record(0, name, BOOTSTAGEF_ALLOC, 95 tse->entry_stamp / 96 get_tbclk_mhz()); 97 } 98 } 99 100 return 0; 101 } 102