source: mainline/kernel/arch/arm64/src/mach/hikey960/hikey960.c

Last change on this file was ebb3538, checked in by Martin Decky <martin@…>, 4 years ago

Improve early kernel debugging prints

Since the early kernel debugging prints are useful only in a few
debugging scenarios, define a configuration option that disables them by
default (if enabled, it produces duplicate output which might be
confusing).

Implement early kernel debugging prints for the HiKey960.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * Copyright (c) 2021 Martin Decky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_arm64_hikey960
30 * @{
31 */
32/** @file
33 * @brief HiKey 960 platform driver.
34 */
35
36#include <arch/mach/hikey960/hikey960.h>
37#include <console/console.h>
38#include <genarch/drivers/gicv2/gicv2.h>
39#include <genarch/drivers/pl011/pl011.h>
40#include <genarch/srln/srln.h>
41#include <mm/km.h>
42#include <sysinfo/sysinfo.h>
43
44#define HIKEY960_VTIMER_IRQ 27
45#define HIKEY960_UART_IRQ 111
46#define HIKEY960_GIC_DISTR_ADDRESS 0xE82B1000
47#define HIKEY960_GIC_CPUI_ADDRESS 0xE82B2000
48#define HIKEY960_UART_ADDRESS 0xFFF32000
49
50struct {
51 gicv2_t gicv2;
52 pl011_uart_t uart;
53} hikey960;
54
55static void hikey960_init(void)
56{
57 /* Initialize interrupt controller. */
58 gicv2_distr_regs_t *distr = (void *) km_map(HIKEY960_GIC_DISTR_ADDRESS,
59 ALIGN_UP(sizeof(*distr), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
60 PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
61 gicv2_cpui_regs_t *cpui = (void *) km_map(HIKEY960_GIC_CPUI_ADDRESS,
62 ALIGN_UP(sizeof(*cpui), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
63 PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
64 gicv2_init(&hikey960.gicv2, distr, cpui);
65}
66
67static void hikey960_irq_exception(unsigned int exc_no, istate_t *istate)
68{
69 unsigned int inum, cpuid;
70 gicv2_inum_get(&hikey960.gicv2, &inum, &cpuid);
71
72 /* Dispatch the interrupt. */
73 irq_t *irq = irq_dispatch_and_lock(inum);
74 if (irq) {
75 /* The IRQ handler was found. */
76 irq->handler(irq);
77 irq_spinlock_unlock(&irq->lock, false);
78 } else {
79 /* Spurious interrupt. */
80 printf("cpu%d: spurious interrupt (inum=%u)\n", CPU->id, inum);
81 }
82
83 /* Signal end of interrupt to the controller. */
84 gicv2_end(&hikey960.gicv2, inum, cpuid);
85}
86
87static void hikey960_output_init(void)
88{
89 if (!pl011_uart_init(&hikey960.uart, HIKEY960_UART_IRQ,
90 HIKEY960_UART_ADDRESS))
91 return;
92
93 stdout_wire(&hikey960.uart.outdev);
94}
95
96static void hikey960_input_init(void)
97{
98 srln_instance_t *srln_instance = srln_init();
99 if (srln_instance == NULL)
100 return;
101
102 indev_t *sink = stdin_wire();
103 indev_t *srln = srln_wire(srln_instance, sink);
104 pl011_uart_input_wire(&hikey960.uart, srln);
105 gicv2_enable(&hikey960.gicv2, HIKEY960_UART_IRQ);
106}
107
108static inr_t hikey960_enable_vtimer_irq(void)
109{
110 gicv2_enable(&hikey960.gicv2, HIKEY960_VTIMER_IRQ);
111 return HIKEY960_VTIMER_IRQ;
112}
113
114static size_t hikey960_get_irq_count(void)
115{
116 return gicv2_inum_get_total(&hikey960.gicv2);
117}
118
119static const char *hikey960_get_platform_name(void)
120{
121 return "hikey960";
122}
123
124static void hikey960_early_uart_output(char32_t c)
125{
126 volatile uint32_t *uartdr = (volatile uint32_t *)
127 PA2KA(HIKEY960_UART_ADDRESS);
128 volatile uint32_t *uartfr = (volatile uint32_t *)
129 PA2KA(HIKEY960_UART_ADDRESS + 24);
130
131 while (*uartfr & 0x20U) {
132 }
133
134 *uartdr = c;
135}
136
137struct arm_machine_ops hikey960_machine_ops = {
138 hikey960_init,
139 hikey960_irq_exception,
140 hikey960_output_init,
141 hikey960_input_init,
142 hikey960_enable_vtimer_irq,
143 hikey960_get_irq_count,
144 hikey960_get_platform_name,
145 hikey960_early_uart_output
146};
147
148/** @}
149 */
Note: See TracBrowser for help on using the repository browser.