From patchwork Wed Aug 21 16:33:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Damien Hedde X-Patchwork-Id: 1150985 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=greensocs.com Authentication-Results: ozlabs.org; dkim=temperror (0-bit key; secure) header.d=greensocs.com header.i=@greensocs.com header.b="2hh4BAez"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46DDKy5Dydz9s3Z for ; Thu, 22 Aug 2019 02:55:02 +1000 (AEST) Received: from localhost ([::1]:50606 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0Tsy-0002D4-59 for incoming@patchwork.ozlabs.org; Wed, 21 Aug 2019 12:55:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59714) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0Ta8-0007tg-5g for qemu-devel@nongnu.org; Wed, 21 Aug 2019 12:35:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0Ta6-0006Cd-PU for qemu-devel@nongnu.org; Wed, 21 Aug 2019 12:35:32 -0400 Received: from beetle.greensocs.com ([5.135.226.135]:36506) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0Ta6-0006Bt-Fl for qemu-devel@nongnu.org; Wed, 21 Aug 2019 12:35:30 -0400 Received: from kouign-amann.bar.greensocs.com (unknown [172.16.11.117]) by beetle.greensocs.com (Postfix) with ESMTPS id 37FC296F56; Wed, 21 Aug 2019 16:35:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1566405329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0BR3eridDeouQ+ZfE9j4HBjTSNzRxIpuXQwC0lZSXRw=; b=2hh4BAez+k2D75Mso0k7eea36N1cRG5Vw0XGPBO+50R4TDtQskzOXCnnrea3c4swsdard+ 6RNuD7BKc1cKf7QpFL49CM2H6lL0QzhUB43a82fI0DX19hzDm++cxl6XWAGSPmbEnr9N/4 EHxtvwT67qyvOb4nmo9w9TGtPiWbnL4= From: Damien Hedde To: qemu-devel@nongnu.org Date: Wed, 21 Aug 2019 18:33:41 +0200 Message-Id: <20190821163341.16309-11-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190821163341.16309-1-damien.hedde@greensocs.com> References: <20190821163341.16309-1-damien.hedde@greensocs.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=greensocs.com; s=mail; t=1566405329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0BR3eridDeouQ+ZfE9j4HBjTSNzRxIpuXQwC0lZSXRw=; b=C6cas6EmaSKbb/7RvHLBDI+LBytvNe17O7DS2ja5KD+tjb+L0qrF4Mf/qnoyBRmWSLXYtN xxwYEZiNDw7NeBRqSf1uyrN6GidMbDnzEJzQ4dl5Y1tmzRJVBkREZwPQ/uvSY+8xcmMhuH ViDinnU+kKmcyFyCsI+fxnlsZpBswA8= ARC-Seal: i=1; s=mail; d=greensocs.com; t=1566405329; a=rsa-sha256; cv=none; b=auUOw8C4R+1wmvrmoFFW3MpmAuPceMMtoj5n3r2Qf9nYuf3cnzNeyvjiyU/0leAteZIA/C OF2gp3K7rNZVSshUIs8RSdDVQqDJVG13wdlwnYumr3Uqi7N3SwzPly5b63DoAKjD+83NYo oeuPxqVrcm2El/9mNQJ3HUuib5tLMog= ARC-Authentication-Results: i=1; beetle.greensocs.com; none X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 5.135.226.135 Subject: [Qemu-devel] [PATCH v4 10/10] docs/devel/reset.txt: add documentation about warm reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Damien Hedde , peter.maydell@linaro.org, edgar.iglesias@xilinx.com, berrange@redhat.com, ehabkost@redhat.com, mark.burton@greensocs.com, pbonzini@redhat.com, philmd@redhat.com, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Complete the documentation with the handling of several reset types (cold and warm). Signed-off-by: Damien Hedde --- docs/devel/reset.txt | 55 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/devel/reset.txt b/docs/devel/reset.txt index 77ff29b3d7..ed1a72566d 100644 --- a/docs/devel/reset.txt +++ b/docs/devel/reset.txt @@ -31,16 +31,21 @@ makes no difference. But there can be some; some configuration may be kept when applying a warm reset for example. The Resettable interface handles reset kinds with an enum. For now only cold -reset is defined, others may be added later. +and warm reset are defined, others may be added later. ``` typedef enum ResetType { RESET_TYPE_COLD, + RESET_TYPE_WARM, } ResetType; ``` In qemu, RESET_TYPE_COLD means we reset to the initial state corresponding to the start of qemu; this might differs from what is a read hardware cold reset. +Although the interface can handle several kind of resets, these are not totally +independant and disjoint. There are some constraints; these are explained below +in the "multi-phase" section. + Triggering reset ---------------- @@ -49,21 +54,41 @@ This section documents the APIs which "users" of a resettable object should use to control it. All resettable control functions must be called while holding the iothread lock. -You can trigger a reset event on a resettable object with resettable_reset(). -The object will be instantly reset. +A resettable object can be put into its "in reset" state and held there +indefinitely. + +You must call resettable_assert_reset() to put an object in reset. It will stay +in this state until you eventually call resettable_deassert_reset(). Care must +be taken to call resettable_deassert_reset() once and only once per call of +resettable_assert_reset(). + +```resettable_assert_reset(Object *obj, ResetType type);``` +The parameter "obj" is an object implementing the Resettable interface. +The parameter "type" gives the type of reset you want to trigger. + +```resettable_deassert_reset(Object *obj);``` +The parameter "obj" is an object implementing the Resettable interface. + +If you want to just trigger a reset event but not leave the object in reset for +any period of time, you can use resettable_reset(), which is a convenience +function identical in behaviour to calling resettable_assert() and then +immediately calling resettable_deassert(). ```void resettable_reset(Object *obj, ResetType type);``` The parameter "obj" is an object implementing the Resettable interface. The parameter "type" gives the type of reset you want to trigger. It is possible to interleave multiple calls to + - resettable_assert_reset(), + - resettable_deassert_reset(), - resettable_reset(). There may be several reset sources/controllers of a given object. The interface handles everything and the different reset controllers do not need to know anything about each others. The object will leave reset state only when each other controllers end their reset operation. This point is handled by -maintaining a count of reset. +maintaining a count of reset; this is why resettable_deassert_reset() must be +called once and only once per resettable_assert_reset(). Note that it is a programming error to call a resettable function on a non-Resettable object and it will trigger a run time assert error. Since most @@ -74,6 +99,8 @@ For Devices and Buses, the following helper functions exists: ``` void device_cold_reset(Device *dev); void bus_cold_reset(Bus *bus); +void device_warm_reset(Device *dev); +void bus_warm_reset(Bus *bus); ``` These are simple wrappers around resettable_reset() function; they only cast the @@ -123,6 +150,25 @@ The exit phase is executed only when the last reset operation ends. Therefore the object has not to care how many reset controllers it has and how many of them have started a reset. +An exception to that is when entering a new reset type AND if there was no +previous cold reset; in that case, init and hold methods are executed again +because the different reset type may reset more things than the previous one +has done. + +For example if some controller has started a RESET_TYPE_WARM with +resettable_assert_reset() on a device and another controller does a +device_cold_reset() on the same object, then the init phase is executed with +RESET_TYPE_COLD as an argument and then the hold phase. +If the first reset was a cold reset, then the warm reset would have triggered +nothing because the cold reset is "stronger". + +Note also that the exit phase will never be executed twice; it will only be +executed when all reset operation are closed, independently of the number of +reset types that were issued. This is a limitation of the interface, there is +only a global count of reset (not a count per reset type). The consequence is +that the different reset types must be close enough in behavior to not require +different exit phases. + Handling reset in a new resettable object ----------------------------------------- @@ -203,6 +249,7 @@ interface. typedef struct ResetState { uint32_t count; bool hold_phase_needed; + ResetType type; } ResetState; typedef ResetState *(*ResettableGetState)(Object *obj);