[haiku-commits] r42882 - haiku/trunk/src/add-ons/kernel/drivers/timer

  • From: stefano.ceccherini@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 19 Oct 2011 14:40:13 +0200 (CEST)

Author: jackburton
Date: 2011-10-19 14:40:12 +0200 (Wed, 19 Oct 2011)
New Revision: 42882
Changeset: https://dev.haiku-os.org/changeset/42882

Modified:
   haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.cpp
   haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.h
Log:
Reorganized defines in the header.
Deallocate resources correcly in error case. Support for level and edge
interrupts.
Removed volatile keyword where it's not needed.


Modified: haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.cpp
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.cpp       2011-10-19 
11:11:53 UTC (rev 42881)
+++ haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.cpp       2011-10-19 
12:40:12 UTC (rev 42882)
@@ -14,6 +14,7 @@
 #include <ACPI.h>
 #include <PCI.h>
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -38,6 +39,7 @@
        int number;
        int32 irq;
        sem_id sem;
+       hpet_timer* timer;
 };
 
 
////////////////////////////////////////////////////////////////////////////////
@@ -92,7 +94,7 @@
 #define MIN_TIMEOUT 1
 
 static status_t
-hpet_set_hardware_timer(bigtime_t relativeTimeout, volatile hpet_timer *timer)
+hpet_set_hardware_timer(bigtime_t relativeTimeout, hpet_timer *timer)
 {
        // TODO:
        if (relativeTimeout < MIN_TIMEOUT)
@@ -116,7 +118,7 @@
 
 
 static status_t
-hpet_clear_hardware_timer(volatile hpet_timer *timer)
+hpet_clear_hardware_timer(hpet_timer *timer)
 {
        // Disable timer interrupt
        timer->config &= ~HPET_CONF_TIMER_INT_ENABLE;
@@ -129,12 +131,14 @@
 {
        //dprintf("HPET timer_interrupt!!!!\n");
        hpet_timer_cookie* hpetCookie = (hpet_timer_cookie*)arg;
+       hpet_timer* timer = &sHPETRegs->timer[hpetCookie->number];
 
-       // clear interrupt status
        int32 intStatus = 1 << hpetCookie->number;
-       if (sHPETRegs->interrupt_status & intStatus) {
+       if (!HPET_GET_CONF_TIMER_INT_IS_LEVEL(timer)
+                       || (sHPETRegs->interrupt_status & intStatus)) {
+               // clear interrupt status
                sHPETRegs->interrupt_status |= intStatus;
-               
hpet_clear_hardware_timer(&sHPETRegs->timer[hpetCookie->number]);
+               hpet_clear_hardware_timer(timer);
                
                release_sem_etc(hpetCookie->sem, 1, B_DO_NOT_RESCHEDULE);
                return B_HANDLED_INTERRUPT;
@@ -159,7 +163,7 @@
 hpet_set_legacy(bool enabled)
 {
        if (!HPET_IS_LEGACY_CAPABLE(sHPETRegs)) {
-               dprintf("hpet_init: HPET doesn't support legacy mode. 
Skipping.\n");
+               dprintf("hpet_init: HPET doesn't support legacy mode.\n");
                return B_NOT_SUPPORTED;
        }
 
@@ -197,7 +201,7 @@
        dprintf("\tTimer type: %s\n",
                timer->config & HPET_CONF_TIMER_TYPE ? "Periodic" : "OneShot");
        dprintf("\tInterrupt Type: %s\n",
-               timer->config & HPET_CONF_TIMER_INT_TYPE ? "Level" : "Edge");
+               HPET_GET_CONF_TIMER_INT_IS_LEVEL(timer) ? "Level" : "Edge");
 
        dprintf("\tconfigured IRQ: %lld\n",
                HPET_GET_CONF_TIMER_INT_ROUTE(timer));
@@ -213,7 +217,7 @@
 static status_t
 hpet_init_timer(hpet_timer_cookie* cookie)
 {
-       volatile struct hpet_timer *timer = &sHPETRegs->timer[cookie->number];
+       struct hpet_timer *timer = cookie->timer;
 
        uint32 interrupts = (uint32)HPET_GET_CAP_TIMER_ROUTE(timer);
 
@@ -226,9 +230,10 @@
                }
        }
 
-       if (interrupt == -1)
+       if (interrupt == -1) {
+               dprintf("hpet_init_timer(): timer can't be routed to any 
interrupt!")
                return B_ERROR;
-
+       }
        // Non-periodic mode
        timer->config &= ~HPET_CONF_TIMER_TYPE;
 
@@ -287,10 +292,9 @@
        sHPETPeriod = HPET_GET_PERIOD(sHPETRegs);
 
        TRACE(("hpet_init: HPET is at %p.\n"
-                       "\tVendor ID: %llx, rev: %llx, period: %lld\n"
-                       "\tin legacy mode: %s\n",
+                       "\tVendor ID: %llx, rev: %llx, period: %lld\n",
                sHPETRegs, HPET_GET_VENDOR_ID(sHPETRegs), 
HPET_GET_REVID(sHPETRegs),
-               sHPETPeriod, sHPETRegs->config & HPET_CONF_MASK_LEGACY ? "yes" 
: "no"));
+               sHPETPeriod));
 
        status_t status = hpet_set_enabled(false);
        if (status != B_OK)
@@ -302,8 +306,10 @@
 
        uint32 numTimers = HPET_GET_NUM_TIMERS(sHPETRegs) + 1;
 
-       TRACE(("hpet_init: HPET supports %lu timers, and is %s bits wide.\n",
-               numTimers, HPET_IS_64BIT(sHPETRegs) ? "64" : "32"));
+       TRACE(("hpet_init: HPET supports %lu timers, is %s bits wide, "
+                       "and is %sin legacy mode.\n",
+                       numTimers, HPET_IS_64BIT(sHPETRegs) ? "64" : "32",
+                       sHPETRegs->config & HPET_CONF_MASK_LEGACY ? "" : "not 
"));
 
        TRACE(("hpet_init: configuration: 0x%llx, timer_interrupts: 0x%llx\n",
                sHPETRegs->config, sHPETRegs->interrupt_status));
@@ -428,27 +434,44 @@
                return B_BUSY;
        }
 
+       int timerNumber = 2;
+               // TODO
+
+       char semName[B_OS_NAME_LENGTH];
+       snprintf(semName, B_OS_NAME_LENGTH, "hpet_timer %d sem", timerNumber);
+       sem_id sem = create_sem(0, semName);
+       if (sem < 0) {
+               atomic_add(&sOpenCount, -1);
+               return sem;
+       }
+
        hpet_timer_cookie* hpetCookie = 
(hpet_timer_cookie*)malloc(sizeof(hpet_timer_cookie));
-       int timerNumber = 2;
+       if (hpetCookie == NULL) {
+               delete_sem(sem);
+               atomic_add(&sOpenCount, -1);
+               return B_NO_MEMORY;
+       }
+
        hpetCookie->number = timerNumber;
-       hpetCookie->sem = create_sem(0, "hpet_timer 2 sem");
+       hpetCookie->timer = &sHPETRegs->timer[timerNumber];
+       hpetCookie->sem = sem;
        set_sem_owner(hpetCookie->sem, B_SYSTEM_TEAM);
 
        hpet_set_enabled(false);
 
        status_t status = hpet_init_timer(hpetCookie);
-       if (status != B_OK) {
+       if (status != B_OK)
                dprintf("hpet_open: initializing timer failed: %s\n", 
strerror(status));
-               return status;
-       }
 
        hpet_set_enabled(true);
 
        *cookie = hpetCookie;
 
-       if (status != B_OK)
+       if (status != B_OK) {
+               delete_sem(sem);
+               free(hpetCookie);
                atomic_add(&sOpenCount, -1);
-
+       }
        return status;
 }
 

Modified: haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.h
===================================================================
--- haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.h 2011-10-19 11:11:53 UTC 
(rev 42881)
+++ haiku/trunk/src/add-ons/kernel/drivers/timer/hpet.h 2011-10-19 12:40:12 UTC 
(rev 42882)
@@ -12,20 +12,20 @@
 /* Doing it this way is Required since the HPET only supports 32/64-bit 
aligned reads. */
 
 /* Global Capability Register Masks */
-#define HPET_CAP_MASK_REVID                    0x00000000000000FFULL
+#define HPET_CAP_MASK_REVID                            0x00000000000000FFULL
 #define HPET_CAP_MASK_NUMTIMERS                        0x0000000000001F00ULL
-#define HPET_CAP_MASK_WIDTH                    0x0000000000002000ULL
+#define HPET_CAP_MASK_WIDTH                            0x0000000000002000ULL
 #define HPET_CAP_MASK_LEGACY                   0x0000000000008000ULL
 #define HPET_CAP_MASK_VENDOR_ID                        0x00000000FFFF0000ULL
 #define HPET_CAP_MASK_PERIOD                   0xFFFFFFFF00000000ULL
 
 /* Retrieve Global Capabilities */
-#define HPET_GET_REVID(regs)           ((regs)->capabilities & 
HPET_CAP_MASK_REVID)
-#define HPET_GET_NUM_TIMERS(regs)      (((regs)->capabilities & 
HPET_CAP_MASK_NUMTIMERS) >> 8)
-#define HPET_IS_64BIT(regs)            (((regs)->capabilities & 
HPET_CAP_MASK_WIDTH) >> 13)
+#define HPET_GET_REVID(regs)                   ((regs)->capabilities & 
HPET_CAP_MASK_REVID)
+#define HPET_GET_NUM_TIMERS(regs)              (((regs)->capabilities & 
HPET_CAP_MASK_NUMTIMERS) >> 8)
+#define HPET_IS_64BIT(regs)                            (((regs)->capabilities 
& HPET_CAP_MASK_WIDTH) >> 13)
 #define HPET_IS_LEGACY_CAPABLE(regs)   (((regs)->capabilities & 
HPET_CAP_MASK_LEGACY) >> 15)
-#define HPET_GET_VENDOR_ID(regs)       (((regs)->capabilities & 
HPET_CAP_MASK_VENDOR_ID) >> 16)
-#define HPET_GET_PERIOD(regs)          (((regs)->capabilities & 
HPET_CAP_MASK_PERIOD) >> 32)
+#define HPET_GET_VENDOR_ID(regs)               (((regs)->capabilities & 
HPET_CAP_MASK_VENDOR_ID) >> 16)
+#define HPET_GET_PERIOD(regs)                  (((regs)->capabilities & 
HPET_CAP_MASK_PERIOD) >> 32)
 
 /* Global Config Register Masks */
 #define HPET_CONF_MASK_ENABLED                 0x00000001
@@ -37,20 +37,21 @@
 
 /* Timer Configuration and Capabilities*/
 #define HPET_CAP_TIMER_MASK                    0xFFFFFFFF00000000ULL
+#define HPET_CAP_TIMER_PER_INT         0x00000010UL
+#define HPET_CAP_TIMER_SIZE                    0x00000020UL
+#define HPET_CAP_TIMER_FSB_INT_DEL     0x00008000UL
+#define HPET_GET_CAP_TIMER_ROUTE(timer)                (((timer)->config & 
HPET_CAP_TIMER_MASK) >> 32)
+
 #define HPET_CONF_TIMER_INT_ROUTE_MASK         0x3e00UL
 #define HPET_CONF_TIMER_INT_ROUTE_SHIFT                9       
-#define HPET_CONF_TIMER_INT_TYPE               0x00000002UL
-#define HPET_CONF_TIMER_INT_ENABLE             0x00000004UL
-#define HPET_CONF_TIMER_TYPE                   0x00000008UL
-#define HPET_CONF_TIMER_VAL_SET                        0x00000040UL
-#define HPET_CONF_TIMER_32MODE                 0x00000100UL
-#define HPET_CONF_TIMER_FSB_ENABLE             0x00004000UL
-#define HPET_CAP_TIMER_PER_INT                 0x00000010UL
-#define HPET_CAP_TIMER_SIZE                    0x00000020UL
-#define HPET_CAP_TIMER_FSB_INT_DEL             0x00008000UL
-
-#define HPET_GET_CAP_TIMER_ROUTE(timer)                (((timer)->config & 
HPET_CAP_TIMER_MASK) >> 32)
+#define HPET_CONF_TIMER_INT_TYPE                       0x00000002UL
+#define HPET_CONF_TIMER_INT_ENABLE                     0x00000004UL
+#define HPET_CONF_TIMER_TYPE                           0x00000008UL
+#define HPET_CONF_TIMER_VAL_SET                                0x00000040UL
+#define HPET_CONF_TIMER_32MODE                         0x00000100UL
+#define HPET_CONF_TIMER_FSB_ENABLE                     0x00004000UL
 #define HPET_GET_CONF_TIMER_INT_ROUTE(timer)   (((timer)->config & 
HPET_CONF_TIMER_INT_ROUTE_MASK) >> HPET_CONF_TIMER_INT_ROUTE_SHIFT)
+#define HPET_GET_CONF_TIMER_INT_IS_LEVEL(timer)        (((timer)->config & 
HPET_CONF_TIMER_INT_TYPE))
 
 #define ACPI_HPET_SIGNATURE                    "HPET"
 
@@ -83,16 +84,16 @@
                                                /* Level Tigger: 0 = off, 1 = 
set by hardware, timer is active */
                                                /* Edge Trigger: ignored */
                                                /* Writing 0 will not clear 
these. Must write 1 again. */
-       volatile uint64 reserved3[25];
+       uint64 reserved3[25];
 
        union {
                volatile uint64 counter64;      /* R/W */
                volatile uint32 counter32;
        } u0;
 
-       volatile uint64 reserved4;
+       uint64 reserved4;
 
-       volatile struct hpet_timer timer[1];
+       struct hpet_timer timer[1];
 };
 
 


Other related posts:

  • » [haiku-commits] r42882 - haiku/trunk/src/add-ons/kernel/drivers/timer - stefano . ceccherini