1*0ed1bf01Scheloha /* $OpenBSD: dmtimer.c,v 1.22 2023/09/17 14:50:51 cheloha Exp $ */
28eda2d14Spatrick /*
38eda2d14Spatrick * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org>
48eda2d14Spatrick * Copyright (c) 2013 Raphael Graf <r@undefined.ch>
58eda2d14Spatrick *
68eda2d14Spatrick * Permission to use, copy, modify, and distribute this software for any
78eda2d14Spatrick * purpose with or without fee is hereby granted, provided that the above
88eda2d14Spatrick * copyright notice and this permission notice appear in all copies.
98eda2d14Spatrick *
108eda2d14Spatrick * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
118eda2d14Spatrick * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
128eda2d14Spatrick * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
138eda2d14Spatrick * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
148eda2d14Spatrick * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
158eda2d14Spatrick * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
168eda2d14Spatrick * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
178eda2d14Spatrick */
188eda2d14Spatrick
198eda2d14Spatrick /*
2097db43afSjsg * WARNING - this timer initialization has not been checked
218eda2d14Spatrick * to see if it will do _ANYTHING_ sane if the omap enters
228eda2d14Spatrick * low power mode.
238eda2d14Spatrick */
248eda2d14Spatrick
258eda2d14Spatrick #include <sys/param.h>
268eda2d14Spatrick #include <sys/systm.h>
278eda2d14Spatrick #include <sys/kernel.h>
289451db9bScheloha #include <sys/clockintr.h>
298eda2d14Spatrick #include <sys/evcount.h>
308eda2d14Spatrick #include <sys/device.h>
319451db9bScheloha #include <sys/stdint.h>
328eda2d14Spatrick #include <sys/timetc.h>
338eda2d14Spatrick #include <machine/bus.h>
348d957e1aSsyl #include <armv7/armv7/armv7var.h>
358eda2d14Spatrick #include <armv7/omap/prcmvar.h>
368eda2d14Spatrick
378eda2d14Spatrick #include <machine/intr.h>
388eda2d14Spatrick
398eda2d14Spatrick /* registers */
408eda2d14Spatrick #define DM_TIDR 0x000
418eda2d14Spatrick #define DM_TIDR_MAJOR 0x00000700
428eda2d14Spatrick #define DM_TIDR_MINOR 0x0000003f
438eda2d14Spatrick #define DM_TIOCP_CFG 0x010
448eda2d14Spatrick #define DM_TIOCP_CFG_IDLEMODE (3<<2)
458eda2d14Spatrick #define DM_TIOCP_CFG_EMUFREE (1<<1)
468eda2d14Spatrick #define DM_TIOCP_CFG_SOFTRESET (1<<0)
478eda2d14Spatrick #define DM_TISR 0x028
488eda2d14Spatrick #define DM_TISR_TCAR (1<<2)
498eda2d14Spatrick #define DM_TISR_OVF (1<<1)
508eda2d14Spatrick #define DM_TISR_MAT (1<<0)
518eda2d14Spatrick #define DM_TIER 0x2c
528eda2d14Spatrick #define DM_TIER_TCAR_EN (1<<2)
538eda2d14Spatrick #define DM_TIER_OVF_EN (1<<1)
548eda2d14Spatrick #define DM_TIER_MAT_EN (1<<0)
558eda2d14Spatrick #define DM_TIECR 0x30
568eda2d14Spatrick #define DM_TIECR_TCAR_EN (1<<2)
578eda2d14Spatrick #define DM_TIECR_OVF_EN (1<<1)
588eda2d14Spatrick #define DM_TIECR_MAT_EN (1<<0)
598eda2d14Spatrick #define DM_TWER 0x034
608eda2d14Spatrick #define DM_TWER_TCAR_EN (1<<2)
618eda2d14Spatrick #define DM_TWER_OVF_EN (1<<1)
628eda2d14Spatrick #define DM_TWER_MAT_EN (1<<0)
638eda2d14Spatrick #define DM_TCLR 0x038
648eda2d14Spatrick #define DM_TCLR_GPO (1<<14)
658eda2d14Spatrick #define DM_TCLR_CAPT (1<<13)
668eda2d14Spatrick #define DM_TCLR_PT (1<<12)
678eda2d14Spatrick #define DM_TCLR_TRG (3<<10)
688eda2d14Spatrick #define DM_TCLR_TRG_O (1<<10)
698eda2d14Spatrick #define DM_TCLR_TRG_OM (2<<10)
708eda2d14Spatrick #define DM_TCLR_TCM (3<<8)
718eda2d14Spatrick #define DM_TCLR_TCM_RISE (1<<8)
728eda2d14Spatrick #define DM_TCLR_TCM_FALL (2<<8)
738eda2d14Spatrick #define DM_TCLR_TCM_BOTH (3<<8)
748eda2d14Spatrick #define DM_TCLR_SCPWM (1<<7)
758eda2d14Spatrick #define DM_TCLR_CE (1<<6)
768eda2d14Spatrick #define DM_TCLR_PRE (1<<5)
778eda2d14Spatrick #define DM_TCLR_PTV (7<<2)
788eda2d14Spatrick #define DM_TCLR_AR (1<<1)
798eda2d14Spatrick #define DM_TCLR_ST (1<<0)
808eda2d14Spatrick #define DM_TCRR 0x03c
818eda2d14Spatrick #define DM_TLDR 0x040
828eda2d14Spatrick #define DM_TTGR 0x044
838eda2d14Spatrick #define DM_TWPS 0x048
848eda2d14Spatrick #define DM_TWPS_TMAR (1<<4)
858eda2d14Spatrick #define DM_TWPS_TTGR (1<<3)
868eda2d14Spatrick #define DM_TWPS_TLDR (1<<2)
878eda2d14Spatrick #define DM_TWPS_TCLR (1<<0)
888eda2d14Spatrick #define DM_TWPS_TCRR (1<<1)
898eda2d14Spatrick #define DM_TWPS_ALL 0x1f
908eda2d14Spatrick #define DM_TMAR 0x04c
918eda2d14Spatrick #define DM_TCAR 0x050
928eda2d14Spatrick #define DM_TSICR 0x054
938eda2d14Spatrick #define DM_TSICR_POSTED (1<<2)
948eda2d14Spatrick #define DM_TSICR_SFT (1<<1)
958eda2d14Spatrick #define DM_TCAR2 0x058
968eda2d14Spatrick
978eda2d14Spatrick #define TIMER_FREQUENCY 32768 /* 32kHz is used, selectable */
988eda2d14Spatrick #define MAX_TIMERS 2
998eda2d14Spatrick
1008eda2d14Spatrick void dmtimer_attach(struct device *parent, struct device *self, void *args);
1018eda2d14Spatrick int dmtimer_intr(void *frame);
1029451db9bScheloha void dmtimer_reset_tisr(void);
1038eda2d14Spatrick void dmtimer_wait(int reg);
1048eda2d14Spatrick void dmtimer_cpu_initclocks(void);
10511d1f9b2Scheloha void dmtimer_cpu_startclock(void);
1068eda2d14Spatrick void dmtimer_delay(u_int);
1078eda2d14Spatrick void dmtimer_setstatclockrate(int newhz);
1088eda2d14Spatrick
1098eda2d14Spatrick u_int dmtimer_get_timecount(struct timecounter *);
1108eda2d14Spatrick
1118eda2d14Spatrick static struct timecounter dmtimer_timecounter = {
1128611d3cdScheloha .tc_get_timecount = dmtimer_get_timecount,
1138611d3cdScheloha .tc_counter_mask = 0xffffffff,
1148611d3cdScheloha .tc_frequency = 0,
1158611d3cdScheloha .tc_name = "dmtimer",
1168611d3cdScheloha .tc_quality = 0,
1178611d3cdScheloha .tc_priv = NULL,
1188eda2d14Spatrick };
1198eda2d14Spatrick
1209451db9bScheloha void dmtimer_rearm(void *, uint64_t);
1219451db9bScheloha void dmtimer_trigger(void *);
1229451db9bScheloha
1239451db9bScheloha struct intrclock dmtimer_intrclock = {
1249451db9bScheloha .ic_rearm = dmtimer_rearm,
1259451db9bScheloha .ic_trigger = dmtimer_trigger
1269451db9bScheloha };
1279451db9bScheloha
1288eda2d14Spatrick bus_space_handle_t dmtimer_ioh0;
1298eda2d14Spatrick int dmtimer_irq = 0;
1308eda2d14Spatrick
1318eda2d14Spatrick struct dmtimer_softc {
1328eda2d14Spatrick struct device sc_dev;
1338eda2d14Spatrick bus_space_tag_t sc_iot;
1348eda2d14Spatrick bus_space_handle_t sc_ioh[MAX_TIMERS];
1358eda2d14Spatrick u_int32_t sc_irq;
1368eda2d14Spatrick u_int32_t sc_ticks_per_second;
1379451db9bScheloha u_int64_t sc_nsec_cycle_ratio;
1389451db9bScheloha u_int64_t sc_nsec_max;
1398eda2d14Spatrick };
1408eda2d14Spatrick
1419fdf0c62Smpi const struct cfattach dmtimer_ca = {
1428eda2d14Spatrick sizeof (struct dmtimer_softc), NULL, dmtimer_attach
1438eda2d14Spatrick };
1448eda2d14Spatrick
1458eda2d14Spatrick struct cfdriver dmtimer_cd = {
1468eda2d14Spatrick NULL, "dmtimer", DV_DULL
1478eda2d14Spatrick };
1488eda2d14Spatrick
1498eda2d14Spatrick void
dmtimer_attach(struct device * parent,struct device * self,void * args)1508eda2d14Spatrick dmtimer_attach(struct device *parent, struct device *self, void *args)
1518eda2d14Spatrick {
1528eda2d14Spatrick struct dmtimer_softc *sc = (struct dmtimer_softc *)self;
1538d957e1aSsyl struct armv7_attach_args *aa = args;
1548eda2d14Spatrick bus_space_handle_t ioh;
1558eda2d14Spatrick u_int32_t rev, cfg;
1568eda2d14Spatrick
1578d957e1aSsyl sc->sc_iot = aa->aa_iot;
1588eda2d14Spatrick
1598d957e1aSsyl if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr,
1608d957e1aSsyl aa->aa_dev->mem[0].size, 0, &ioh))
1614123b6a7Sderaadt panic("%s: bus_space_map failed!", __func__);
1628eda2d14Spatrick
1638eda2d14Spatrick
1648eda2d14Spatrick prcm_setclock(1, PRCM_CLK_SPEED_32);
1658eda2d14Spatrick prcm_setclock(2, PRCM_CLK_SPEED_32);
1668eda2d14Spatrick prcm_enablemodule(PRCM_TIMER2);
1678eda2d14Spatrick prcm_enablemodule(PRCM_TIMER3);
1688eda2d14Spatrick
1698eda2d14Spatrick /* reset */
1708eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TIOCP_CFG,
1718eda2d14Spatrick DM_TIOCP_CFG_SOFTRESET);
1728eda2d14Spatrick while (bus_space_read_4(sc->sc_iot, ioh, DM_TIOCP_CFG)
1738eda2d14Spatrick & DM_TIOCP_CFG_SOFTRESET)
1748eda2d14Spatrick ;
1758eda2d14Spatrick
1768eda2d14Spatrick if (self->dv_unit == 0) {
1778eda2d14Spatrick dmtimer_ioh0 = ioh;
1788d957e1aSsyl dmtimer_irq = aa->aa_dev->irq[0];
1798eda2d14Spatrick /* enable write posted mode */
1808eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TSICR, DM_TSICR_POSTED);
1818eda2d14Spatrick /* stop timer */
1828eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TCLR, 0);
1838eda2d14Spatrick } else if (self->dv_unit == 1) {
1848eda2d14Spatrick /* start timer because it is used in delay */
1858eda2d14Spatrick /* interrupts and posted mode are disabled */
1868eda2d14Spatrick sc->sc_irq = dmtimer_irq;
1878eda2d14Spatrick sc->sc_ioh[0] = dmtimer_ioh0;
1888eda2d14Spatrick sc->sc_ioh[1] = ioh;
1898eda2d14Spatrick
1908eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TCRR, 0);
1918eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TLDR, 0);
1928eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TCLR,
1938eda2d14Spatrick DM_TCLR_AR | DM_TCLR_ST);
1948eda2d14Spatrick
1958eda2d14Spatrick dmtimer_timecounter.tc_frequency = TIMER_FREQUENCY;
1968eda2d14Spatrick dmtimer_timecounter.tc_priv = sc;
1978eda2d14Spatrick tc_init(&dmtimer_timecounter);
1988eda2d14Spatrick arm_clock_register(dmtimer_cpu_initclocks, dmtimer_delay,
19911d1f9b2Scheloha dmtimer_setstatclockrate, dmtimer_cpu_startclock);
2008eda2d14Spatrick }
2018eda2d14Spatrick else
202ddb53a58Smiod panic("attaching too many dmtimers at 0x%lx",
2038d957e1aSsyl aa->aa_dev->mem[0].addr);
2048eda2d14Spatrick
2058eda2d14Spatrick /* set IDLEMODE to smart-idle */
2068eda2d14Spatrick cfg = bus_space_read_4(sc->sc_iot, ioh, DM_TIOCP_CFG);
2078eda2d14Spatrick bus_space_write_4(sc->sc_iot, ioh, DM_TIOCP_CFG,
2088eda2d14Spatrick (cfg & ~DM_TIOCP_CFG_IDLEMODE) | 0x02);
2098eda2d14Spatrick
2108eda2d14Spatrick rev = bus_space_read_4(sc->sc_iot, ioh, DM_TIDR);
2118eda2d14Spatrick printf(" rev %d.%d\n", (rev & DM_TIDR_MAJOR) >> 8, rev & DM_TIDR_MINOR);
2128eda2d14Spatrick }
2138eda2d14Spatrick
2148eda2d14Spatrick int
dmtimer_intr(void * frame)2158eda2d14Spatrick dmtimer_intr(void *frame)
2168eda2d14Spatrick {
2179451db9bScheloha dmtimer_reset_tisr(); /* clear pending interrupts */
2189451db9bScheloha clockintr_dispatch(frame);
2198eda2d14Spatrick return 1;
2208eda2d14Spatrick }
2218eda2d14Spatrick
2228eda2d14Spatrick /*
2238eda2d14Spatrick * would be interesting to play with trigger mode while having one timer
2242252d02cSkettenis * in 32kHz mode, and the other timer running in sysclk mode and use
2258eda2d14Spatrick * the high resolution speeds (matters more for delay than tick timer
2268eda2d14Spatrick */
2278eda2d14Spatrick
2288eda2d14Spatrick void
dmtimer_cpu_initclocks(void)22937e35e27Sjsg dmtimer_cpu_initclocks(void)
2308eda2d14Spatrick {
2318eda2d14Spatrick struct dmtimer_softc *sc = dmtimer_cd.cd_devs[1];
2328eda2d14Spatrick
2334533a266Scheloha stathz = hz;
2344533a266Scheloha profhz = stathz * 10;
235b3ef18bdScheloha statclock_is_randomized = 1;
2368eda2d14Spatrick
2378eda2d14Spatrick sc->sc_ticks_per_second = TIMER_FREQUENCY; /* 32768 */
2389451db9bScheloha sc->sc_nsec_cycle_ratio =
2399451db9bScheloha sc->sc_ticks_per_second * (1ULL << 32) / 1000000000;
2409451db9bScheloha sc->sc_nsec_max = UINT64_MAX / sc->sc_nsec_cycle_ratio;
2419451db9bScheloha dmtimer_intrclock.ic_cookie = sc;
2428eda2d14Spatrick
2438eda2d14Spatrick /* establish interrupts */
2448eda2d14Spatrick arm_intr_establish(sc->sc_irq, IPL_CLOCK, dmtimer_intr,
2458eda2d14Spatrick NULL, "tick");
2468eda2d14Spatrick
2478eda2d14Spatrick /* setup timer 0 */
2488eda2d14Spatrick bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TLDR, 0);
2498eda2d14Spatrick bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TIER, DM_TIER_OVF_EN);
2508eda2d14Spatrick bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TWER, DM_TWER_OVF_EN);
25111d1f9b2Scheloha }
2529451db9bScheloha
25311d1f9b2Scheloha void
dmtimer_cpu_startclock(void)25411d1f9b2Scheloha dmtimer_cpu_startclock(void)
25511d1f9b2Scheloha {
2569451db9bScheloha /* start the clock interrupt cycle */
2579451db9bScheloha clockintr_cpu_init(&dmtimer_intrclock);
2589451db9bScheloha clockintr_trigger();
2598eda2d14Spatrick }
2608eda2d14Spatrick
2618eda2d14Spatrick void
dmtimer_wait(int reg)2628eda2d14Spatrick dmtimer_wait(int reg)
2638eda2d14Spatrick {
2648eda2d14Spatrick struct dmtimer_softc *sc = dmtimer_cd.cd_devs[1];
2658eda2d14Spatrick while (bus_space_read_4(sc->sc_iot, sc->sc_ioh[0], DM_TWPS) & reg)
2668eda2d14Spatrick ;
2678eda2d14Spatrick }
2688eda2d14Spatrick
2699451db9bScheloha /*
2709451db9bScheloha * Clear all interrupt status bits.
2719451db9bScheloha */
2729451db9bScheloha void
dmtimer_reset_tisr(void)2739451db9bScheloha dmtimer_reset_tisr(void)
2749451db9bScheloha {
2759451db9bScheloha struct dmtimer_softc *sc = dmtimer_cd.cd_devs[1];
2769451db9bScheloha u_int32_t tisr;
2779451db9bScheloha
2789451db9bScheloha tisr = bus_space_read_4(sc->sc_iot, sc->sc_ioh[0], DM_TISR);
2799451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TISR, tisr);
2809451db9bScheloha }
2819451db9bScheloha
2828eda2d14Spatrick void
dmtimer_delay(u_int usecs)2838eda2d14Spatrick dmtimer_delay(u_int usecs)
2848eda2d14Spatrick {
2858eda2d14Spatrick struct dmtimer_softc *sc = dmtimer_cd.cd_devs[1];
2868eda2d14Spatrick u_int32_t clock, oclock, delta, delaycnt;
2878eda2d14Spatrick volatile int j;
2888eda2d14Spatrick int csec, usec;
2898eda2d14Spatrick
2908eda2d14Spatrick if (usecs > (0x80000000 / (TIMER_FREQUENCY))) {
2918eda2d14Spatrick csec = usecs / 10000;
2928eda2d14Spatrick usec = usecs % 10000;
2938eda2d14Spatrick
2948eda2d14Spatrick delaycnt = (TIMER_FREQUENCY / 100) * csec +
2958eda2d14Spatrick (TIMER_FREQUENCY / 100) * usec / 10000;
2968eda2d14Spatrick } else {
2978eda2d14Spatrick delaycnt = TIMER_FREQUENCY * usecs / 1000000;
2988eda2d14Spatrick }
2998eda2d14Spatrick if (delaycnt <= 1)
3008eda2d14Spatrick for (j = 100; j > 0; j--)
3018eda2d14Spatrick ;
3028eda2d14Spatrick
3038eda2d14Spatrick if (sc->sc_ioh[1] == 0) {
3048eda2d14Spatrick /* BAH */
3058eda2d14Spatrick for (; usecs > 0; usecs--)
3068eda2d14Spatrick for (j = 100; j > 0; j--)
3078eda2d14Spatrick ;
3088eda2d14Spatrick return;
3098eda2d14Spatrick }
3108eda2d14Spatrick oclock = bus_space_read_4(sc->sc_iot, sc->sc_ioh[1], DM_TCRR);
3118eda2d14Spatrick while (1) {
3128eda2d14Spatrick for (j = 100; j > 0; j--)
3138eda2d14Spatrick ;
3148eda2d14Spatrick clock = bus_space_read_4(sc->sc_iot, sc->sc_ioh[1], DM_TCRR);
3158eda2d14Spatrick delta = clock - oclock;
3168eda2d14Spatrick if (delta > delaycnt)
3178eda2d14Spatrick break;
3188eda2d14Spatrick }
3198eda2d14Spatrick
3208eda2d14Spatrick }
3218eda2d14Spatrick
3228eda2d14Spatrick void
dmtimer_setstatclockrate(int newhz)3238eda2d14Spatrick dmtimer_setstatclockrate(int newhz)
3248eda2d14Spatrick {
3258eda2d14Spatrick }
3268eda2d14Spatrick
3278eda2d14Spatrick
3288eda2d14Spatrick u_int
dmtimer_get_timecount(struct timecounter * tc)3298eda2d14Spatrick dmtimer_get_timecount(struct timecounter *tc)
3308eda2d14Spatrick {
3318eda2d14Spatrick struct dmtimer_softc *sc = dmtimer_timecounter.tc_priv;
3328eda2d14Spatrick
3338eda2d14Spatrick return bus_space_read_4(sc->sc_iot, sc->sc_ioh[1], DM_TCRR);
3348eda2d14Spatrick }
3359451db9bScheloha
3369451db9bScheloha void
dmtimer_rearm(void * cookie,uint64_t nsecs)3379451db9bScheloha dmtimer_rearm(void *cookie, uint64_t nsecs)
3389451db9bScheloha {
3399451db9bScheloha struct dmtimer_softc *sc = cookie;
3409451db9bScheloha uint32_t cycles;
3419451db9bScheloha
3429451db9bScheloha if (nsecs > sc->sc_nsec_max)
3439451db9bScheloha nsecs = sc->sc_nsec_max;
3449451db9bScheloha cycles = (nsecs * sc->sc_nsec_cycle_ratio) >> 32;
3459451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TCRR,
3469451db9bScheloha UINT32_MAX - cycles);
3479451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TCLR, DM_TCLR_ST);
3489451db9bScheloha dmtimer_wait(DM_TWPS_ALL);
3499451db9bScheloha }
3509451db9bScheloha
3519451db9bScheloha void
dmtimer_trigger(void * cookie)3529451db9bScheloha dmtimer_trigger(void *cookie)
3539451db9bScheloha {
3549451db9bScheloha struct dmtimer_softc *sc = cookie;
3559451db9bScheloha
3569451db9bScheloha /* stop timer */
3579451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TCLR, 0);
3589451db9bScheloha
3599451db9bScheloha dmtimer_reset_tisr(); /* clear pending interrupts */
3609451db9bScheloha
3619451db9bScheloha /* set shortest possible timeout */
3629451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TCRR, UINT32_MAX);
3639451db9bScheloha dmtimer_wait(DM_TWPS_ALL);
3649451db9bScheloha
3659451db9bScheloha /* start timer */
3669451db9bScheloha bus_space_write_4(sc->sc_iot, sc->sc_ioh[0], DM_TCLR, DM_TCLR_ST);
3679451db9bScheloha dmtimer_wait(DM_TWPS_ALL);
3689451db9bScheloha }
369