2 * Copyright (c) 2012 Matteo Facchinetti
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 /** @addtogroup arm32beaglebone
32 * @brief BeagleBone platform driver.
35 #include <arch/exception.h>
36 #include <arch/mach/beaglebone/beaglebone.h>
37 #include <genarch/drivers/am335x/irc.h>
38 #include <genarch/drivers/am335x/uart.h>
39 #include <genarch/drivers/am335x/timer.h>
40 #include <genarch/srln/srln.h>
41 #include <interrupt.h>
43 #include <ddi/device.h>
46 #define BBONE_MEMORY_START 0x80000000 /* physical */
47 #define BBONE_MEMORY_SIZE 0x10000000 /* 256 MB */
49 static void bbone_init(void);
50 static void bbone_timer_irq_start(void);
51 static void bbone_cpu_halt(void);
52 static void bbone_get_memory_extents(uintptr_t *start
, size_t *size
);
53 static void bbone_irq_exception(unsigned int exc_no
, istate_t
*istate
);
54 static void bbone_frame_init(void);
55 static void bbone_output_init(void);
56 static void bbone_input_init(void);
57 static size_t bbone_get_irq_count(void);
58 static const char *bbone_get_platform_name(void);
60 static struct beaglebone
{
61 am335x_irc_regs_t
*irc_addr
;
66 struct arm_machine_ops bbone_machine_ops
= {
67 .machine_init
= bbone_init
,
68 .machine_timer_irq_start
= bbone_timer_irq_start
,
69 .machine_cpu_halt
= bbone_cpu_halt
,
70 .machine_get_memory_extents
= bbone_get_memory_extents
,
71 .machine_irq_exception
= bbone_irq_exception
,
72 .machine_frame_init
= bbone_frame_init
,
73 .machine_output_init
= bbone_output_init
,
74 .machine_input_init
= bbone_input_init
,
75 .machine_get_irq_count
= bbone_get_irq_count
,
76 .machine_get_platform_name
= bbone_get_platform_name
,
79 static void bbone_init(void)
81 /* Initialize the interrupt controller */
82 bbone
.irc_addr
= (void *) km_map(AM335x_IRC_BASE_ADDRESS
,
83 AM335x_IRC_SIZE
, PAGE_NOT_CACHEABLE
);
85 am335x_irc_init(bbone
.irc_addr
);
88 static irq_ownership_t
bbone_timer_irq_claim(irq_t
*irq
)
93 static void bbone_timer_irq_handler(irq_t
*irq
)
95 am335x_timer_intr_ack(&bbone
.timer
);
96 spinlock_unlock(&irq
->lock
);
98 spinlock_lock(&irq
->lock
);
101 static void bbone_timer_irq_start(void)
103 /* Initialize the IRQ */
104 static irq_t timer_irq
;
105 irq_initialize(&timer_irq
);
106 timer_irq
.devno
= device_assign_devno();
107 timer_irq
.inr
= AM335x_DMTIMER0_IRQ
;
108 timer_irq
.claim
= bbone_timer_irq_claim
;
109 timer_irq
.handler
= bbone_timer_irq_handler
;
110 irq_register(&timer_irq
);
112 /* Initialize the DMTIMER0 */
113 am335x_timer_init(&bbone
.timer
, DMTIMER0
, HZ
);
114 /* Enable the interrupt */
115 am335x_irc_enable(bbone
.irc_addr
, AM335x_DMTIMER0_IRQ
);
116 /* Start the timer */
117 am335x_timer_start(&bbone
.timer
);
120 static void bbone_cpu_halt(void)
125 /** Get extents of available memory.
127 * @param start Place to store memory start address (physical).
128 * @param size Place to store memory size.
130 static void bbone_get_memory_extents(uintptr_t *start
, size_t *size
)
132 *start
= BBONE_MEMORY_START
;
133 *size
= BBONE_MEMORY_SIZE
;
136 static void bbone_irq_exception(unsigned int exc_no
, istate_t
*istate
)
138 const unsigned inum
= am335x_irc_inum_get(bbone
.irc_addr
);
139 am335x_irc_irq_ack(bbone
.irc_addr
);
141 irq_t
*irq
= irq_dispatch_and_lock(inum
);
143 /* The IRQ handler was found. */
145 spinlock_unlock(&irq
->lock
);
147 printf("Spurious interrupt\n");
151 static void bbone_frame_init(void)
155 static void bbone_output_init(void)
157 const bool ok
= am335x_uart_init(&bbone
.uart
,
158 AM335x_UART0_IRQ
, AM335x_UART0_BASE_ADDRESS
,
162 stdout_wire(&bbone
.uart
.outdev
);
167 static void bbone_input_init(void)
169 srln_instance_t
*srln_instance
= srln_init();
171 indev_t
*sink
= stdin_wire();
172 indev_t
*srln
= srln_wire(srln_instance
, sink
);
173 am335x_uart_input_wire(&bbone
.uart
, srln
);
174 am335x_irc_enable(bbone
.irc_addr
, AM335x_UART0_IRQ
);
178 size_t bbone_get_irq_count(void)
180 return AM335x_IRC_IRQ_COUNT
;
183 const char *bbone_get_platform_name(void)