summaryrefslogtreecommitdiff
path: root/arch/x86/cpu/quark/car.S
blob: 48d5167c74661fd5ef27db8be8336dc95879c2c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
 */

#include <config.h>
#include <asm/pci.h>
#include <asm/post.h>
#include <asm/arch/quark.h>
#include <asm/arch/msg_port.h>

.globl car_init
car_init:
	post_code(POST_CAR_START)

	/*
	 * Quark SoC contains an embedded 512KiB SRAM (eSRAM) that is
	 * initialized by hardware. eSRAM is the ideal place to be used
	 * for Cache-As-RAM (CAR) before system memory is available.
	 *
	 * Relocate this eSRAM to a suitable location in the physical
	 * memory map and enable it.
	 */

	/* Host Memory Bound Register P03h:R08h */
	mov	$((MSG_PORT_HOST_BRIDGE << 16) | (HM_BOUND << 8)), %eax
	mov	$(DRAM_BASE + DRAM_MAX_SIZE + ESRAM_SIZE), %edx
	lea	1f, %esp
	jmp	msg_port_write
1:

	/* eSRAM Block Page Control Register P05h:R82h */
	mov	$((MSG_PORT_MEM_MGR << 16) | (ESRAM_BLK_CTRL << 8)), %eax
	mov	$(ESRAM_BLOCK_MODE | (CONFIG_ESRAM_BASE >> 24)), %edx
	lea	2f, %esp
	jmp	msg_port_write
2:

	post_code(POST_CAR_CPU_CACHE)
	jmp	car_init_ret

msg_port_read:
	/*
	 * Parameter:
	 *   eax[23:16] - Message Port ID
	 *   eax[15:08] - Register Address
	 *
	 * Return Value:
	 *   eax - Message Port Register value
	 *
	 * Return Address: esp
	 */

	or	$((MSG_OP_READ << 24) | MSG_BYTE_ENABLE), %eax
	mov	%eax, %ebx

	/* Write MCR B0:D0:F0:RD0 */
	mov	$(PCI_CFG_EN | MSG_CTRL_REG), %eax
	mov	$PCI_REG_ADDR, %dx
	out	%eax, %dx
	mov	$PCI_REG_DATA, %dx
	mov	%ebx, %eax
	out	%eax, %dx

	/* Read MDR B0:D0:F0:RD4 */
	mov	$(PCI_CFG_EN | MSG_DATA_REG), %eax
	mov	$PCI_REG_ADDR, %dx
	out	%eax, %dx
	mov	$PCI_REG_DATA, %dx
	in	%dx, %eax

	jmp	*%esp

msg_port_write:
	/*
	 * Parameter:
	 *   eax[23:16] - Message Port ID
	 *   eax[15:08] - Register Address
	 *   edx        - Message Port Register value to write
	 *
	 * Return Address: esp
	 */

	or	$((MSG_OP_WRITE << 24) | MSG_BYTE_ENABLE), %eax
	mov	%eax, %esi
	mov	%edx, %edi

	/* Write MDR B0:D0:F0:RD4 */
	mov	$(PCI_CFG_EN | MSG_DATA_REG), %eax
	mov	$PCI_REG_ADDR, %dx
	out	%eax, %dx
	mov	$PCI_REG_DATA, %dx
	mov	%edi, %eax
	out	%eax, %dx

	/* Write MCR B0:D0:F0:RD0 */
	mov	$(PCI_CFG_EN | MSG_CTRL_REG), %eax
	mov	$PCI_REG_ADDR, %dx
	out	%eax, %dx
	mov	$PCI_REG_DATA, %dx
	mov	%esi, %eax
	out	%eax, %dx

	jmp	*%esp