mail.coreboot.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

coreboot-gerrit

Download
Threads by month
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2013 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
coreboot-gerrit@coreboot.org

April 2013

  • 1 participants
  • 506 discussions
New patch to review for coreboot: 9ab4574 device tree: optionally track init times
by Aaron Durbin April 30, 2013

April 30, 2013
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3162 -gerrit commit 9ab4574110cbf18329e5706586a56c74f0938b40 Author: Aaron Durbin <adurbin(a)chromium.org> Date: Tue Apr 30 15:41:13 2013 -0500 device tree: optionally track init times With the introduction of a monotonic timer it is possible to track the individual times of each device's init() call. Add this ability behind a DEV_INIT_TIMES Kconfig option. Example log messages: Root Device init 5 usecs CPU_CLUSTER: 0 init 66004 usecs PCI: 00:00.0 init 1020 usecs PCI: 00:02.0 init 456941 usecs PCI: 00:13.0 init 3 usecs PCI: 00:14.0 init 3 usecs PCI: 00:15.0 init 92 usecs PCI: 00:15.1 init 37 usecs PCI: 00:15.2 init 36 usecs PCI: 00:15.3 init 35 usecs PCI: 00:15.4 init 35 usecs PCI: 00:15.5 init 36 usecs PCI: 00:15.6 init 35 usecs PCI: 00:16.0 init 3666 usecs PCI: 00:17.0 init 63 usecs PCI: 00:1b.0 init 3 usecs PCI: 00:1c.0 init 89 usecs PCI: 00:1c.1 init 15 usecs PCI: 00:1c.2 init 15 usecs PCI: 00:1c.3 init 15 usecs PCI: 00:1c.4 init 15 usecs PCI: 00:1c.5 init 16 usecs PCI: 00:1d.0 init 4 usecs PCI: 00:1f.0 init 495 usecs PCI: 00:1f.2 init 29 usecs PCI: 00:1f.3 init 4 usecs PCI: 00:1f.6 init 4 usecs Change-Id: Ibe499848432c7ab20166ab10d6dfb07db03eab01 Signed-off-by: Aaron Durbin <adurbin(a)chromium.org> --- src/Kconfig | 6 ++++++ src/device/device.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index ab2a927..11355c2 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -324,6 +324,12 @@ config TIMER_QUEUE help Provide a timer queue for performing time-based callbacks. +config DEV_INIT_TIMES + def_bool n + depends on HAVE_MONOTONIC_TIMER + help + Track the times each device takes to initialize in the device tree. + config HIGH_SCRATCH_MEMORY_SIZE hex default 0x0 diff --git a/src/device/device.c b/src/device/device.c index e0c8bf0..ac786ff 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -43,6 +43,7 @@ #if CONFIG_ARCH_X86 #include <arch/ebda.h> #endif +#include <timer.h> /** Linked list of ALL devices */ struct device *all_devices = &dev_root; @@ -1103,6 +1104,12 @@ static void init_dev(struct device *dev) return; if (!dev->initialized && dev->ops && dev->ops->init) { +#if CONFIG_DEV_INIT_TIMES + struct mono_time start_time; + struct rela_time dev_init_time; + + timer_monotonic_get(&start_time); +#endif if (dev->path.type == DEVICE_PATH_I2C) { printk(BIOS_DEBUG, "smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link_num); @@ -1111,6 +1118,11 @@ static void init_dev(struct device *dev) printk(BIOS_DEBUG, "%s init\n", dev_path(dev)); dev->initialized = 1; dev->ops->init(dev); +#if CONFIG_DEV_INIT_TIMES + dev_init_time = current_time_from(&start_time); + printk(BIOS_DEBUG, "%s init %ld usecs\n", dev_path(dev), + rela_time_in_microseconds(&dev_init_time)); +#endif } }
1 0
0 0
New patch to review for coreboot: 03a52d8 armv7: add wrapper for tlbimvaa
by David Hendricks April 30, 2013

April 30, 2013
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3161 -gerrit commit 03a52d8d2c747b62b262152dff01cd50ecff6b50 Author: David Hendricks <dhendrix(a)chromium.org> Date: Tue Apr 30 12:20:53 2013 -0700 armv7: add wrapper for tlbimvaa This adds an inline wrapper for the TLBIMVAA instruction (invalidate unified TLB by MVA, all address space identifiers). Change-Id: Ibcd289ecedaba8586ade26e36c177ff1fcaf91d3 Signed-off-by: David Hendricks <dhendrix(a)chromium.org> --- src/arch/armv7/include/arch/cache.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/arch/armv7/include/arch/cache.h b/src/arch/armv7/include/arch/cache.h index 1db86dc..028cf18 100644 --- a/src/arch/armv7/include/arch/cache.h +++ b/src/arch/armv7/include/arch/cache.h @@ -108,6 +108,12 @@ static inline void tlbiall(void) asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0) : "memory"); } +/* invalidate unified TLB by MVA, all ASID */ +static inline void tlbimvaa(unsigned long mva) +{ + asm volatile ("mcr p15, 0, %0, c8, c7, 3" : : "r" (mva) : "memory"); +} + /* write data access control register (DACR) */ static inline void write_dacr(uint32_t val) {
1 0
0 0
Patch set updated for coreboot: cedf48e Google/Snow: Remove duplicated SPI1 initialization in bootblock.
by David Hendricks April 30, 2013

April 30, 2013
David Hendricks (dhendrix(a)chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3147 -gerrit commit cedf48e463e287f647b13d2de1c1fbda7199f0ea Author: Hung-Te Lin <hungte(a)chromium.org> Date: Tue Apr 30 16:11:32 2013 +0800 Google/Snow: Remove duplicated SPI1 initialization in bootblock. The firmware media source (SPI1) is already initialized by Exynos iROM. There is no need to do it again. Verified by building and booting Google/Snow successfully. Change-Id: I89390506aa825397c0d7e52ad7503f1cb808f7db Signed-off-by: Hung-Te Lin <hungte(a)chromium.org> --- src/mainboard/google/snow/bootblock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/snow/bootblock.c b/src/mainboard/google/snow/bootblock.c index 1746290..4a78946 100644 --- a/src/mainboard/google/snow/bootblock.c +++ b/src/mainboard/google/snow/bootblock.c @@ -40,8 +40,13 @@ void bootblock_mainboard_init(void) * We want to do this as early as we can. */ timer_start(); - exynos_pinmux_config(PERIPH_ID_SPI1, PINMUX_FLAG_NONE); break; } + + /* For most ARM systems, we have to initialize firmware media source + * (ex, SPI, SD/MMC, or eMMC) now; but for Exynos platform, that is + * already handled by iROM so there's no need to setup again. + */ + console_init(); }
1 0
0 0
Patch set updated for coreboot: 010641f coreboot: add timer queue implementation
by Aaron Durbin April 30, 2013

April 30, 2013
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3158 -gerrit commit 010641ff9a394d6fa90c95aae08ca52ef86a80fb Author: Aaron Durbin <adurbin(a)chromium.org> Date: Tue Apr 30 09:58:12 2013 -0500 coreboot: add timer queue implementation A timer queue provides the mechanism for calling functions in the future by way of a callback. It utilizes the MONOTONIC_TIMER to track time through the boot. The implementation is a min-heap for keeping track of the next-to-expire callback. Change-Id: Ia56bab8444cd6177b051752342f53b53d5f6afc1 Signed-off-by: Aaron Durbin <adurbin(a)chromium.org> --- src/Kconfig | 6 ++ src/include/timer.h | 18 +++++ src/lib/Makefile.inc | 1 + src/lib/timer_queue.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index a49643e..ab2a927 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -318,6 +318,12 @@ config HAVE_MONOTONIC_TIMER help The board/chipset provides a monotonic timer. +config TIMER_QUEUE + def_bool n + depends on HAVE_MONOTONIC_TIMER + help + Provide a timer queue for performing time-based callbacks. + config HIGH_SCRATCH_MEMORY_SIZE hex default 0x0 diff --git a/src/include/timer.h b/src/include/timer.h index 2b112dd..e950c81 100644 --- a/src/include/timer.h +++ b/src/include/timer.h @@ -38,6 +38,17 @@ struct rela_time { long microseconds; }; +/* A timeout_callback structure is used for the book keeping for scheduling + * work in the future. When a callback is called the structure can be + * re-used for scheduling as it is not being tracked by the core timer + * library any more. */ +struct timeout_callback { + void *priv; + void (*callback)(struct timeout_callback *tocb); + /* Not for public use. The timer library uses the fields below. */ + struct mono_time expiration; +}; + /* Obtain the current monotonic time. The assumption is that the time counts * up from the value 0 with value 0 being the point when the timer was * initialized. Additionally, the timer is assumed to only be valid for the @@ -49,6 +60,13 @@ struct rela_time { * of 10 seconds. */ void timer_monotonic_get(struct mono_time *mt); +/* Returns 1 if callbacks still present in the queue. 0 if no timers left. */ +int timers_run(void); + +/* Schedule a callback to be ran microseconds from time of invocation. + * 0 returned on success, < 0 on error. */ +int timer_sched_callback(struct timeout_callback *tocb, unsigned long us); + /* Add microseconds to an absoute time. */ static inline void mono_time_add_usecs(struct mono_time *mt, long us) { diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index e8b1485..7306e6d 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -90,6 +90,7 @@ ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c ramstage-$(CONFIG_COVERAGE) += libgcov.c ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += edid.c ramstage-y += memrange.c +ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c # The CBMEM implementations are chosen based on CONFIG_DYNAMIC_CBMEM. ifeq ($(CONFIG_DYNAMIC_CBMEM),y) diff --git a/src/lib/timer_queue.c b/src/lib/timer_queue.c new file mode 100644 index 0000000..8d11f10 --- /dev/null +++ b/src/lib/timer_queue.c @@ -0,0 +1,198 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stddef.h> +#include <timer.h> + +#define MAX_TIMER_QUEUE_ENTRIES 64 + +/* The timer queue is implemented using a min heap. Therefore the first + * element is the one with smallest time to expiration. */ +struct timer_queue { + int num_entries; + int max_entries; + struct timeout_callback *queue[MAX_TIMER_QUEUE_ENTRIES]; +}; + +static struct timer_queue global_timer_queue = { + .num_entries = 0, + .max_entries = MAX_TIMER_QUEUE_ENTRIES, + .queue = { 0 }, +}; + +static inline int timer_queue_empty(struct timer_queue *tq) +{ + return tq->num_entries == 0; +} + +static inline int timer_queue_full(struct timer_queue *tq) +{ + return tq->num_entries == tq->max_entries; +} + +static inline struct timeout_callback *timer_queue_head(struct timer_queue *tq) +{ + if (timer_queue_empty(tq)) + return NULL; + return tq->queue[0]; +} + +static int timer_queue_insert(struct timer_queue *tq, + struct timeout_callback *tocb) +{ + int index; + + /* No more slots. */ + if (timer_queue_full(tq)) + return -1; + + index = tq->num_entries; + tq->num_entries++; + tq->queue[index] = tocb; + + while (index != 0) { + struct timeout_callback *parent; + int parent_index; + + parent_index = (index - 1) / 2; + parent = tq->queue[parent_index]; + + /* All other ancestors are less than or equal to the current. */ + if (mono_time_cmp(&parent->expiration, &tocb->expiration) <= 0) + break; + + /* The parent is greater than current. Swap them. */ + tq->queue[parent_index] = tocb; + tq->queue[index] = parent; + + index = parent_index; + } + + return 0; +} + +/* Get the index containing the entry with smallest value. */ +static int timer_queue_min_child_index(struct timer_queue *tq, int index) +{ + int left_child_index; + int right_child_index; + + left_child_index = 2 * index + 1; + + if (left_child_index >= tq->num_entries) + return -1; + + right_child_index = left_child_index + 1; + + if (right_child_index >= tq->num_entries) + return left_child_index; + + if (mono_time_cmp(&tq->queue[left_child_index]->expiration, + &tq->queue[right_child_index]->expiration) < 0) { + return left_child_index; + } + return right_child_index; +} + +static void timer_queue_remove_head(struct timer_queue *tq) +{ + int index; + struct timeout_callback *tocb; + + /* In order to remove the head the deepest child is replaced in the + * head slot and bubbled down the tree. */ + tq->num_entries--; + tocb = tq->queue[tq->num_entries]; + tq->queue[0] = tocb; + + index = 0; + while (1) { + int min_child_index; + struct timeout_callback *child; + + min_child_index = timer_queue_min_child_index(tq, index); + + /* No more entries to compare against. */ + if (min_child_index < 0) + break; + + child = tq->queue[min_child_index]; + + /* Current index is the correct place since it is smaller or + * equal to the smallest child. */ + if (mono_time_cmp(&tocb->expiration, &child->expiration) <= 0) + break; + + /* Need to swap with smallest child. */ + tq->queue[min_child_index] = tocb; + tq->queue[index] = child; + + index = min_child_index; + } +} + +static struct timeout_callback * +timer_queue_expired(struct timer_queue *tq, struct mono_time *current_time) +{ + struct timeout_callback *tocb; + + tocb = timer_queue_head(tq); + + if (tocb == NULL) + return NULL; + + /* The timeout callback hasn't expired yet. */ + if (mono_time_before(current_time, &tocb->expiration)) + return NULL; + + timer_queue_remove_head(tq); + + return tocb; +} + +int timer_sched_callback(struct timeout_callback *tocb, unsigned long us) +{ + struct mono_time current_time; + + if ((long)us< 0) + return -1; + + timer_monotonic_get(&current_time); + tocb->expiration = current_time; + mono_time_add_usecs(&tocb->expiration, us); + + /* The expiration overflowed. */ + if (us != 0 && !mono_time_before(&current_time, &tocb->expiration)) + return -1; + + return timer_queue_insert(&global_timer_queue, tocb); +} + +int timers_run(void) +{ + struct timeout_callback *tocb; + struct mono_time current_time; + + timer_monotonic_get(&current_time); + tocb = timer_queue_expired(&global_timer_queue, &current_time); + + if (tocb != NULL) + tocb->callback(tocb); + + return !timer_queue_empty(&global_timer_queue); +}
1 0
0 0
Patch set updated for coreboot: 07206fd boot state: run timers on state entry
by Aaron Durbin April 30, 2013

April 30, 2013
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3159 -gerrit commit 07206fd8eeea2dcb4454edd33985456c8a0b287d Author: Aaron Durbin <adurbin(a)chromium.org> Date: Mon Apr 29 23:22:01 2013 -0500 boot state: run timers on state entry When TIMER_QUEUE is configured on call the timer callbacks on entry into a state but before its entry callbacks. In addition provide a barrier to the following states so that timers are drained before proceeding. This allows for blocking state traversal for key components of boot. BS_OS_RESUME BS_WRITE_TABLES BS_PAYLOAD_LOAD BS_PAYLOAD_BOOT Future functionality consists of evaluating the timer callbacks within the device tree. One example is dev_initialize() as that seems state seems to take 90% of the boot time. The timer callbacks could then be ran in a more granular manner. Change-Id: Idb549ea17c5ec38eb57b4f6f366a1c2183f4a6dd Signed-off-by: Aaron Durbin <adurbin(a)chromium.org> --- src/lib/hardwaremain.c | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c index 7bf0237..8e5481e 100644 --- a/src/lib/hardwaremain.c +++ b/src/lib/hardwaremain.c @@ -78,23 +78,27 @@ struct boot_state { struct boot_state_callback *seq_callbacks[2]; boot_state_t (*run_state)(void *arg); void *arg; - int complete; + int complete : 1; + int timers_drain : 1; #if CONFIG_HAVE_MONOTONIC_TIMER struct boot_state_times times; #endif }; -#define BS_INIT(state_, run_func_) \ - { \ - .name = #state_, \ - .id = state_, \ - .seq_callbacks = { NULL, NULL },\ - .run_state = run_func_, \ - .arg = NULL, \ - .complete = 0 \ +#define BS_INIT(state_, run_func_, drain_timers_) \ + { \ + .name = #state_, \ + .id = state_, \ + .seq_callbacks = { NULL, NULL }, \ + .run_state = run_func_, \ + .arg = NULL, \ + .complete = 0, \ + .timers_drain = drain_timers_, \ } #define BS_INIT_ENTRY(state_, run_func_) \ - [state_] = BS_INIT(state_, run_func_) + [state_] = BS_INIT(state_, run_func_, 0) +#define BS_INIT_ENTRY_DRAIN_TIMERS(state_, run_func_) \ + [state_] = BS_INIT(state_, run_func_, 1) static struct boot_state boot_states[] = { BS_INIT_ENTRY(BS_PRE_DEVICE, bs_pre_device), @@ -105,10 +109,10 @@ static struct boot_state boot_states[] = { BS_INIT_ENTRY(BS_DEV_INIT, bs_dev_init), BS_INIT_ENTRY(BS_POST_DEVICE, bs_post_device), BS_INIT_ENTRY(BS_OS_RESUME_CHECK, bs_os_resume_check), - BS_INIT_ENTRY(BS_OS_RESUME, bs_os_resume), - BS_INIT_ENTRY(BS_WRITE_TABLES, bs_write_tables), - BS_INIT_ENTRY(BS_PAYLOAD_LOAD, bs_payload_load), - BS_INIT_ENTRY(BS_PAYLOAD_BOOT, bs_payload_boot), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_OS_RESUME, bs_os_resume), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_WRITE_TABLES, bs_write_tables), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_LOAD, bs_payload_load), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_BOOT, bs_payload_boot), }; static boot_state_t bs_pre_device(void *arg) @@ -278,6 +282,20 @@ static inline void bs_sample_time(struct boot_state *state) {} static inline void bs_report_time(struct boot_state *state) {} #endif +#if CONFIG_TIMER_QUEUE +static void bs_run_timers(int drain) +{ + /* Drain all timer callbacks until none are left, if directed. + * Otherwise run the timers only once. */ + do { + if (!timers_run()) + break; + } while (drain); +} +#else +static void bs_run_timers(int drain) {} +#endif + static void bs_call_callbacks(struct boot_state *state, boot_state_sequence_t seq) { @@ -313,6 +331,8 @@ static void bs_walk_state_machine(boot_state_t current_state_id) printk(BS_DEBUG_LVL, "BS: Entering %s state.\n", state->name); + bs_run_timers(state->timers_drain); + bs_sample_time(state); bs_call_callbacks(state, BS_ON_ENTRY);
1 0
0 0
Patch merged into coreboot/master: 032dd14 Google/Snow: Remove unnecessary serial console init code.
by gerrit@coreboot.org April 30, 2013

April 30, 2013
the following patch was just integrated into master: commit 032dd14514e72777475c3e39395486627846b7c9 Author: Hung-Te Lin <hungte(a)chromium.org> Date: Tue Apr 30 15:31:48 2013 +0800 Google/Snow: Remove unnecessary serial console init code. The "console_init" does initialize UART driver (which will setup peripheral and pinmux) and print starting message. Duplicated initialization can be removed. Also, console_init (from console.c) is always linked to bootblock (and will do nothing if CONFIG_EARLY_CONSOLE is not defined) so it's safe to remove #ifdef. Verified by building and booting on Google/Snow, with and without CONFIG_EARLY_CONSOLE. Change-Id: I0c6b4d4eb1a4e81af0f65bcb032978dfb945c63d Signed-off-by: Hung-Te Lin <hungte(a)chromium.org> Reviewed-on: http://review.coreboot.org/3150 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net> Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com> Build-Tested: build bot (Jenkins) at Tue Apr 30 11:07:01 2013, giving +1 Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Tue Apr 30 19:22:05 2013, giving +2 See http://review.coreboot.org/3150 for details. -gerrit
1 0
0 0
New patch to review for coreboot: 32a3d97 ARMV7: add a function to disable MMU entries
by Ronald G. Minnich April 30, 2013

April 30, 2013
Ronald G. Minnich (rminnich(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3160 -gerrit commit 32a3d97b1f0357e33977f65ce719fa0e27a8de83 Author: Ronald G. Minnich <rminnich(a)gmail.com> Date: Tue Apr 30 10:11:30 2013 -0700 ARMV7: add a function to disable MMU entries It is useful to be able to lock out certain address ranges, NULL being the most important example. void mmu_disable_range(unsigned long start_mb, unsigned long size_mb) Will allow us to lock out selected virtual addresses on MiB boundaries. As in other ARM mmu functions, the addresses and quantities are in units of MiB. Change-Id: If516ce955ee2d12c5a409f25acbb5a4b424f699b Signed-off-by: Ronald G. Minnich <rminnich(a)gmail.com> --- src/arch/armv7/include/arch/cache.h | 2 ++ src/arch/armv7/lib/mmu.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/arch/armv7/include/arch/cache.h b/src/arch/armv7/include/arch/cache.h index 1db86dc..df335a0 100644 --- a/src/arch/armv7/include/arch/cache.h +++ b/src/arch/armv7/include/arch/cache.h @@ -297,6 +297,8 @@ enum dcache_policy { DCACHE_WRITETHROUGH, }; +/* disable the mmu for a range. Primarily useful to lock out address 0. */ +void mmu_disable_range(unsigned long start_mb, unsigned long size_mb); /* mmu range configuration (set dcache policy) */ void mmu_config_range(unsigned long start_mb, unsigned long size_mb, enum dcache_policy policy); diff --git a/src/arch/armv7/lib/mmu.c b/src/arch/armv7/lib/mmu.c index 224b566..9d61c56 100644 --- a/src/arch/armv7/lib/mmu.c +++ b/src/arch/armv7/lib/mmu.c @@ -39,6 +39,20 @@ static uintptr_t ttb_addr; +void mmu_disable_range(unsigned long start_mb, unsigned long size_mb) +{ + unsigned int i; + uint32_t *ttb_entry = (uint32_t *)ttb_addr; + printk(BIOS_DEBUG, "Disabling: 0x%08lx:0x%08lx\n", + start_mb << 20, ((start_mb + size_mb) << 20) - 1); + + for (i = start_mb; i < start_mb + size_mb; i++) + ttb_entry[i] = 0; + + /* TODO: add helper to invalidate TLB by MVA */ + tlb_invalidate_all(); +} + void mmu_config_range(unsigned long start_mb, unsigned long size_mb, enum dcache_policy policy) {
1 0
0 0
New patch to review for coreboot: be64eeb coreboot: add timer queue implementation
by Aaron Durbin April 30, 2013

April 30, 2013
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3158 -gerrit commit be64eeb18e62067b0bb49d99fcb68e15e6403fe1 Author: Aaron Durbin <adurbin(a)chromium.org> Date: Tue Apr 30 09:58:12 2013 -0500 coreboot: add timer queue implementation A timer queue provides the mechanism for calling functions in the future by way of a callback. It utilizes the MONOTONIC_TIMER to track time through the boot. The implementation is a min-heap for keeping track of the next-to-expire callback. Change-Id: Ia56bab8444cd6177b051752342f53b53d5f6afc1 Signed-off-by: Aaron Durbin <adurbin(a)chromium.org> --- src/Kconfig | 6 ++ src/include/timer.h | 18 +++++ src/lib/Makefile.inc | 1 + src/lib/timer_queue.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index a49643e..ab2a927 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -318,6 +318,12 @@ config HAVE_MONOTONIC_TIMER help The board/chipset provides a monotonic timer. +config TIMER_QUEUE + def_bool n + depends on HAVE_MONOTONIC_TIMER + help + Provide a timer queue for performing time-based callbacks. + config HIGH_SCRATCH_MEMORY_SIZE hex default 0x0 diff --git a/src/include/timer.h b/src/include/timer.h index 2b112dd..e950c81 100644 --- a/src/include/timer.h +++ b/src/include/timer.h @@ -38,6 +38,17 @@ struct rela_time { long microseconds; }; +/* A timeout_callback structure is used for the book keeping for scheduling + * work in the future. When a callback is called the structure can be + * re-used for scheduling as it is not being tracked by the core timer + * library any more. */ +struct timeout_callback { + void *priv; + void (*callback)(struct timeout_callback *tocb); + /* Not for public use. The timer library uses the fields below. */ + struct mono_time expiration; +}; + /* Obtain the current monotonic time. The assumption is that the time counts * up from the value 0 with value 0 being the point when the timer was * initialized. Additionally, the timer is assumed to only be valid for the @@ -49,6 +60,13 @@ struct rela_time { * of 10 seconds. */ void timer_monotonic_get(struct mono_time *mt); +/* Returns 1 if callbacks still present in the queue. 0 if no timers left. */ +int timers_run(void); + +/* Schedule a callback to be ran microseconds from time of invocation. + * 0 returned on success, < 0 on error. */ +int timer_sched_callback(struct timeout_callback *tocb, unsigned long us); + /* Add microseconds to an absoute time. */ static inline void mono_time_add_usecs(struct mono_time *mt, long us) { diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index e8b1485..7306e6d 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -90,6 +90,7 @@ ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c ramstage-$(CONFIG_COVERAGE) += libgcov.c ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += edid.c ramstage-y += memrange.c +ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c # The CBMEM implementations are chosen based on CONFIG_DYNAMIC_CBMEM. ifeq ($(CONFIG_DYNAMIC_CBMEM),y) diff --git a/src/lib/timer_queue.c b/src/lib/timer_queue.c new file mode 100644 index 0000000..deb0245 --- /dev/null +++ b/src/lib/timer_queue.c @@ -0,0 +1,200 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stddef.h> +#include <timer.h> + +#define MAX_TIMER_QUEUE_ENTRIES 64 + +/* The timer queue is implemented using a min heap. Therefore the first + * element is the one with smallest time to expiration. */ +struct timer_queue { + int num_entries; + int max_entries; + struct timeout_callback *queue[MAX_TIMER_QUEUE_ENTRIES]; +}; + +static struct timer_queue global_timer_queue = { + .num_entries = 0, + .max_entries = MAX_TIMER_QUEUE_ENTRIES, + .queue = { 0 }, +}; + +static inline int timer_queue_empty(struct timer_queue *tq) +{ + return tq->num_entries == 0; +} + +static inline int timer_queue_full(struct timer_queue *tq) +{ + return tq->num_entries == tq->max_entries; +} + +static inline struct timeout_callback *timer_queue_head(struct timer_queue *tq) +{ + if (timer_queue_empty(tq)) + return NULL; + return tq->queue[0]; +} + +static int timer_queue_insert(struct timer_queue *tq, + struct timeout_callback *tocb) +{ + int index; + + /* No more slots. */ + if (timer_queue_full(tq)) + return -1; + + index = tq->num_entries; + tq->num_entries++; + tq->queue[index] = tocb; + + while (index != 0) { + struct timeout_callback *parent; + int parent_index; + + parent_index = index / 2; + parent = tq->queue[parent_index]; + + /* All other ancestors are less than or equal to the current. */ + if (mono_time_cmp(&parent->expiration, &tocb->expiration) <= 0) + break; + + /* The parent is greater than current. Swap them. */ + tq->queue[parent_index] = tocb; + tq->queue[index] = parent; + + index = parent_index; + } + + return 0; +} + +/* Get the index containing the entry with smallest value. */ +static int timer_queue_min_child_index(struct timer_queue *tq, int index) +{ + int left_child_index; + int right_child_index; + + left_child_index = index * 2; + + if (left_child_index >= tq->num_entries) + return -1; + + right_child_index = left_child_index + 1; + + if (right_child_index >= tq->num_entries) + return left_child_index; + + if (mono_time_cmp(&tq->queue[left_child_index]->expiration, + &tq->queue[right_child_index]->expiration) < 0) { + return left_child_index; + } + return right_child_index; +} + +static void timer_queue_remove_head(struct timer_queue *tq) +{ + int index; + struct timeout_callback *tocb; + + /* In order to remove the head the deepest child is replaced in the + * head slot and bubbled down the tree. */ + tq->num_entries--; + tocb = tq->queue[tq->num_entries]; + tq->queue[0] = tocb; + + index = 0; + while (1) { + int min_child_index; + struct timeout_callback *child; + + min_child_index = timer_queue_min_child_index(tq, index); + + /* No more entries to compare against. */ + if (min_child_index < 0) + break; + + child = tq->queue[min_child_index]; + + /* Current index is the correct place since it is smaller or + * equal to the smallest child. */ + if (mono_time_cmp(&tocb->expiration, &child->expiration) <= 0) + break; + + /* Need to swap with smallest child. */ + tq->queue[min_child_index] = tocb; + tq->queue[index] = child; + + index = min_child_index; + } +} + +static struct timeout_callback * +timer_queue_expired(struct timer_queue *tq, struct mono_time *current_time) +{ + struct timeout_callback *tocb; + + tocb = timer_queue_head(tq); + + if (tocb == NULL) + return NULL; + + tocb = tq->queue[0]; + + /* The timeout callback hasn't expired yet. */ + if (mono_time_before(current_time, &tocb->expiration)) + return NULL; + + timer_queue_remove_head(tq); + + return tocb; +} + +int timer_sched_callback(struct timeout_callback *tocb, unsigned long us) +{ + struct mono_time current_time; + + if ((long)us< 0) + return -1; + + timer_monotonic_get(&current_time); + tocb->expiration = current_time; + mono_time_add_usecs(&tocb->expiration, us); + + /* The expiration overflowed. */ + if (us != 0 && !mono_time_before(&current_time, &tocb->expiration)) + return -1; + + return timer_queue_insert(&global_timer_queue, tocb); +} + +int timers_run(void) +{ + struct timeout_callback *tocb; + struct mono_time current_time; + + timer_monotonic_get(&current_time); + tocb = timer_queue_expired(&global_timer_queue, &current_time); + + if (tocb != NULL) + tocb->callback(tocb); + + return !timer_queue_empty(&global_timer_queue); +}
1 0
0 0
New patch to review for coreboot: 5f52bcc boot state: run timers on state entry
by Aaron Durbin April 30, 2013

April 30, 2013
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3159 -gerrit commit 5f52bcc91ae1dc8f6755a4c5f5b0419a09ca1070 Author: Aaron Durbin <adurbin(a)chromium.org> Date: Mon Apr 29 23:22:01 2013 -0500 boot state: run timers on state entry When TIMER_QUEUE is configured on call the timer callbacks on entry into a state but before its entry callbacks. In addition provide a barrier to the following states so that timers are drained before proceeding. This allows for blocking state traversal for key components of boot. BS_OS_RESUME BS_WRITE_TABLES BS_PAYLOAD_LOAD BS_PAYLOAD_BOOT Future functionality consists of evaluating the timer callbacks within the device tree. One example is dev_initialize() as that seems state seems to take 90% of the boot time. The timer callbacks could then be ran in a more granular manner. Change-Id: Idb549ea17c5ec38eb57b4f6f366a1c2183f4a6dd Signed-off-by: Aaron Durbin <adurbin(a)chromium.org> --- src/lib/hardwaremain.c | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c index 7bf0237..8e5481e 100644 --- a/src/lib/hardwaremain.c +++ b/src/lib/hardwaremain.c @@ -78,23 +78,27 @@ struct boot_state { struct boot_state_callback *seq_callbacks[2]; boot_state_t (*run_state)(void *arg); void *arg; - int complete; + int complete : 1; + int timers_drain : 1; #if CONFIG_HAVE_MONOTONIC_TIMER struct boot_state_times times; #endif }; -#define BS_INIT(state_, run_func_) \ - { \ - .name = #state_, \ - .id = state_, \ - .seq_callbacks = { NULL, NULL },\ - .run_state = run_func_, \ - .arg = NULL, \ - .complete = 0 \ +#define BS_INIT(state_, run_func_, drain_timers_) \ + { \ + .name = #state_, \ + .id = state_, \ + .seq_callbacks = { NULL, NULL }, \ + .run_state = run_func_, \ + .arg = NULL, \ + .complete = 0, \ + .timers_drain = drain_timers_, \ } #define BS_INIT_ENTRY(state_, run_func_) \ - [state_] = BS_INIT(state_, run_func_) + [state_] = BS_INIT(state_, run_func_, 0) +#define BS_INIT_ENTRY_DRAIN_TIMERS(state_, run_func_) \ + [state_] = BS_INIT(state_, run_func_, 1) static struct boot_state boot_states[] = { BS_INIT_ENTRY(BS_PRE_DEVICE, bs_pre_device), @@ -105,10 +109,10 @@ static struct boot_state boot_states[] = { BS_INIT_ENTRY(BS_DEV_INIT, bs_dev_init), BS_INIT_ENTRY(BS_POST_DEVICE, bs_post_device), BS_INIT_ENTRY(BS_OS_RESUME_CHECK, bs_os_resume_check), - BS_INIT_ENTRY(BS_OS_RESUME, bs_os_resume), - BS_INIT_ENTRY(BS_WRITE_TABLES, bs_write_tables), - BS_INIT_ENTRY(BS_PAYLOAD_LOAD, bs_payload_load), - BS_INIT_ENTRY(BS_PAYLOAD_BOOT, bs_payload_boot), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_OS_RESUME, bs_os_resume), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_WRITE_TABLES, bs_write_tables), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_LOAD, bs_payload_load), + BS_INIT_ENTRY_DRAIN_TIMERS(BS_PAYLOAD_BOOT, bs_payload_boot), }; static boot_state_t bs_pre_device(void *arg) @@ -278,6 +282,20 @@ static inline void bs_sample_time(struct boot_state *state) {} static inline void bs_report_time(struct boot_state *state) {} #endif +#if CONFIG_TIMER_QUEUE +static void bs_run_timers(int drain) +{ + /* Drain all timer callbacks until none are left, if directed. + * Otherwise run the timers only once. */ + do { + if (!timers_run()) + break; + } while (drain); +} +#else +static void bs_run_timers(int drain) {} +#endif + static void bs_call_callbacks(struct boot_state *state, boot_state_sequence_t seq) { @@ -313,6 +331,8 @@ static void bs_walk_state_machine(boot_state_t current_state_id) printk(BS_DEBUG_LVL, "BS: Entering %s state.\n", state->name); + bs_run_timers(state->timers_drain); + bs_sample_time(state); bs_call_callbacks(state, BS_ON_ENTRY);
1 0
0 0
Patch merged into coreboot/master: 4560ca5 Lenovo ThinkPad X60: Init CBMEM early for CBMEM console support.
by gerrit@coreboot.org April 30, 2013

April 30, 2013
the following patch was just integrated into master: commit 4560ca5003fe38a066616e8de1a8a414284750fd Author: Denis 'GNUtoo' Carikli <GNUtoo(a)no-log.org> Date: Fri Apr 26 12:21:41 2013 +0200 Lenovo ThinkPad X60: Init CBMEM early for CBMEM console support. Enable `EARLY_CBMEM_INIT` for CBMEM console support by looking how other boards do this. This commit is tested by enabling the CBMEM console (`CONSOLE_CBMEM` in Kconfig) and then in GRUB 2 (as a payload) with the cbmemc command from the cbmemc module and in userspace with ./cbmem -c. Both worked. Change-Id: I34618a55ded7292a411bc232eb76267eec17d91e Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo(a)no-log.org> Reviewed-on: http://review.coreboot.org/3142 Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net> Reviewed-by: Aaron Durbin <adurbin(a)google.com> Tested-by: build bot (Jenkins) Build-Tested: build bot (Jenkins) at Tue Apr 30 16:33:59 2013, giving +1 See http://review.coreboot.org/3142 for details. -gerrit
1 0
0 0
  • ← Newer
  • 1
  • 2
  • 3
  • 4
  • ...
  • 51
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.