1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-01 01:26:43 +03:00

working on lcd

This commit is contained in:
Bas Wijnen 2009-06-10 21:42:01 +02:00
parent 9a7abe2fd5
commit 1bb67efc75
9 changed files with 4470 additions and 266 deletions

View File

@ -183,131 +183,168 @@ do { \
// Pins on the trendtac:
0 keyboard
1 keyboard
2 keyboard
3 keyboard
4 keyboard
5 keyboard
6 keyboard
7 keyboard
8 keyboard interrupt
9
10
11
12
13 touchpad right button
14
15
16 touchpad left button
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 keyboard
97 keyboard
98 keyboard
99 keyboard
100 keyboard
101 keyboard
102 keyboard
103 keyboard
104 keyboard
105 keyboard
106 keyboard
107 keyboard
108 keyboard
109 keyboard
110 keyboard
111 keyboard
112
113
114
115
116
117
118
119
120
121
122
123
124
125 keyboard
126
127
0.00 keyboard
0.01 keyboard
0.02 keyboard
0.03 keyboard
0.04 keyboard
0.05 keyboard
0.06 keyboard
0.07 keyboard
0.08 keyboard interrupt?
0.09
0.10
0.11
0.12
0.13 touchpad right button
0.14
0.15
0.16 touchpad left button
0.17
0.18
0.19
0.20
0.21
0.22
0.23
0.24
0.25
0.26
0.27
0.28
0.29
0.30
0.31
1.00
1.01
1.02
1.03
1.04
1.05
1.06
1.07
1.08
1.09
1.10
1.11
1.12
1.13
1.14
1.15
1.16
1.17
1.18
1.19
1.20
1.21
1.22
1.23
1.24
1.25
1.26
1.27
1.28
1.29
1.30
1.31
2.00 SPEN: lcd enable
2.01 SPCK: lcd clock
2.02 SPDA: lcd data
2.03 LCD_RET: lcd reset
2.04
2.05
2.06
2.07
2.08
2.09
2.10
2.11
2.12
2.13
2.14
2.15
2.16
2.17
2.18
2.19
2.20
2.21
2.22
2.23
2.24
2.25
2.26
2.27
2.28
2.29
2.30 PWM enable (for lcd backlight)
2.31
3.00 keyboard
3.01 keyboard
3.02 keyboard
3.03 keyboard
3.04 keyboard
3.05 keyboard
3.06 keyboard
3.07 keyboard
3.08 keyboard
3.09 keyboard
3.10 keyboard
3.11 keyboard
3.12 keyboard
3.13 keyboard
3.14 keyboard
3.15 keyboard
3.16
3.17
3.18
3.19
3.20
3.21
3.22
3.23
3.24
3.25
3.26
3.27
3.28
3.29 keyboard
3.30
3.31
Devices enabled in linux:
+ __harb_usb0_uhc();
+ __gpio_as_emc();
+ __gpio_as_uart0();
+ __gpio_as_dma();
+ __gpio_as_eth();
+ __gpio_as_usb();
+ __gpio_as_lcd_master();
+#if defined(CONFIG_I2S_AK4642EN)
+//wjx __gpio_as_scc1();
+ __gpio_as_i2s_master(); //wjx
+#endif
+#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23)
+ __gpio_as_ssi();
+#endif
+ //__gpio_as_ac97();
+#if defined(CONFIG_I2S_TSC2301) || defined(CONFIG_I2S_TLC320AIC23) || defined(CONFIG_I2S_CS42L51)
+ __gpio_as_i2s_slave();
+#endif
+//wjx __gpio_as_cim();
+ __gpio_as_msc();
+
+/* wjx
+ __gpio_as_output(GPIO_LED_EN);
+ __gpio_set_pin(GPIO_LED_EN);
+
+ __gpio_as_output(GPIO_DISP_OFF_N);
+ __gpio_set_pin(GPIO_DISP_OFF_N);
+*/
+ __gpio_as_output(GPIO_PWM0);
+ __gpio_set_pin(GPIO_PWM0);
+
+
+//wjx __gpio_as_input(GPIO_RTC_IRQ);
+ __gpio_as_output(GPIO_USB_CLK_EN);
+ __gpio_set_pin(GPIO_USB_CLK_EN);

3901
boot-programs/jz4730.hhp Normal file

File diff suppressed because it is too large Load Diff

326
boot-programs/lcd.ccp Normal file
View File

@ -0,0 +1,326 @@
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// lcd.ccp: Display driver.
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "iris.h"
// gpio stuff
#define D(n) (*(volatile unsigned *)(0x00 + 0x30 * n + gpio_address))
#define DI(n) (*(volatile unsigned *)(0x04 + 0x30 * n + gpio_address))
#define PU(n) (*(volatile unsigned *)(0x0c + 0x30 * n + gpio_address))
#define AL(n) (*(volatile unsigned *)(0x10 + 0x30 * n + gpio_address))
#define AU(n) (*(volatile unsigned *)(0x14 + 0x30 * n + gpio_address))
#define IE(n) (*(volatile unsigned *)(0x20 + 0x30 * n + gpio_address))
// pwm stuff
#define CTR (*(volatile unsigned char *)(pwm_address + 0x00))
#define PER (*(volatile unsigned short *)(pwm_address + 0x04))
#define DUT (*(volatile unsigned short *)(pwm_address + 0x08))
#define CPM_MSCR (*(volatile unsigned *)(cpm_address + 0x20))
// Mapping address for I/O memory.
unsigned const gpio_address = 0x00001000
unsigned const pwm_address = 0x00002000
unsigned const lcd_address = 0x00003000
unsigned const cpm_address = 0x00004000
//#define PWM0_BASE 0xB0050000
//#define PWM1_BASE 0xB0051000
/* PWM Control Register (PWM_CTR) */
//#define PWM_CTR_EN (1 << 7)
//#define PWM_CTR_SD (1 << 6)
//#define PWM_CTR_PRESCALE_MASK 0x3f
/* PWM Period Register (PWM_PER) */
//#define PWM_PER_PERIOD_MASK 0x3ff
/* PWM Duty Register (PWM_DUT) */
//#define PWM_DUT_FDUTY (1 << 10)
//#define PWM_DUT_DUTY_MASK 0x3ff
// Pin definitions, all in port 2.
#define PWM_ENABLE (1 << 30)
#define SPEN (1 << 0) //LCD_SPL
#define SPCK (1 << 1) //LCD_CLS
#define SPDA (1 << 2) //LCD_PS
#define LCD_RET (1 << 3) //LCD_REV //use for lcd reset
// Lcd register definitions.
#define LCD_CFG (*(volatile unsigned *)(lcd_address + 0x00))
#define LCD_VSYNC (*(volatile unsigned *)(lcd_address + 0x04))
#define LCD_HSYNC (*(volatile unsigned *)(lcd_address + 0x08))
#define LCD_VAT (*(volatile unsigned *)(lcd_address + 0x0c))
#define LCD_DAH (*(volatile unsigned *)(lcd_address + 0x10))
#define LCD_DAV (*(volatile unsigned *)(lcd_address + 0x14))
#define LCD_PS (*(volatile unsigned *)(lcd_address + 0x18))
#define LCD_CLS (*(volatile unsigned *)(lcd_address + 0x1c))
#define LCD_SPL (*(volatile unsigned *)(lcd_address + 0x20))
#define LCD_REV (*(volatile unsigned *)(lcd_address + 0x24))
#define LCD_CTRL (*(volatile unsigned *)(lcd_address + 0x30))
#define LCD_STATE (*(volatile unsigned *)(lcd_address + 0x34))
#define LCD_IID (*(volatile unsigned *)(lcd_address + 0x38))
#define LCD_DA0 (*(volatile unsigned *)(lcd_address + 0x40))
#define LCD_SA0 (*(volatile unsigned *)(lcd_address + 0x44))
#define LCD_FID0 (*(volatile unsigned *)(lcd_address + 0x48))
#define LCD_CMD0 (*(volatile unsigned *)(lcd_address + 0x4c))
#define LCD_DA1 (*(volatile unsigned *)(lcd_address + 0x50))
#define LCD_SA1 (*(volatile unsigned *)(lcd_address + 0x54))
#define LCD_FID1 (*(volatile unsigned *)(lcd_address + 0x58))
#define LCD_CMD1 (*(volatile unsigned *)(lcd_address + 0x5c))
// Bit definitions.
#define LCD_CFG_PDW_BIT 4
#define LCD_CFG_PDW_MASK (0x03 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_1 (0 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_2 (1 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_4 (2 << LCD_DEV_PDW_BIT)
#define LCD_CFG_PDW_8 (3 << LCD_DEV_PDW_BIT)
#define LCD_CFG_MODE_BIT 0
#define LCD_CFG_MODE_MASK (0x0f << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_GENERIC_TFT (0 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SHARP_HR (1 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_CASIO_TFT (2 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SAMSUNG_ALPHA (3 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_NONINTER_CCIR656 (4 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_INTER_CCIR656 (5 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_CSTN (8 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_SINGLE_MSTN (9 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_CSTN (10 << LCD_DEV_MODE_BIT)
#define LCD_CFG_MODE_DUAL_MSTN (11 << LCD_DEV_MODE_BIT)
#define LCD_VSYNC_VPS_BIT 16
#define LCD_VSYNC_VPS_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_VSYNC_VPE_BIT 0
#define LCD_VSYNC_VPE_MASK (0xffff << LCD_VSYNC_VPS_BIT)
#define LCD_HSYNC_HPS_BIT 16
#define LCD_HSYNC_HPS_MASK (0xffff << LCD_HSYNC_HPS_BIT)
#define LCD_HSYNC_HPE_BIT 0
#define LCD_HSYNC_HPE_MASK (0xffff << LCD_HSYNC_HPE_BIT)
#define LCD_VAT_HT_BIT 16
#define LCD_VAT_HT_MASK (0xffff << LCD_VAT_HT_BIT)
#define LCD_VAT_VT_BIT 0
#define LCD_VAT_VT_MASK (0xffff << LCD_VAT_VT_BIT)
#define LCD_DAH_HDS_BIT 16
#define LCD_DAH_HDS_MASK (0xffff << LCD_DAH_HDS_BIT)
#define LCD_DAH_HDE_BIT 0
#define LCD_DAH_HDE_MASK (0xffff << LCD_DAH_HDE_BIT)
#define LCD_DAV_VDS_BIT 16
#define LCD_DAV_VDS_MASK (0xffff << LCD_DAV_VDS_BIT)
#define LCD_DAV_VDE_BIT 0
#define LCD_DAV_VDE_MASK (0xffff << LCD_DAV_VDE_BIT)
#define LCD_CTRL_BST_BIT 28
#define LCD_CTRL_BST_MASK (0x03 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_4 (0 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_8 (1 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_BST_16 (2 << LCD_CTRL_BST_BIT)
#define LCD_CTRL_RGB555 (1 << 27)
#define LCD_CTRL_OFUP (1 << 26)
#define LCD_CTRL_FRC_BIT 24
#define LCD_CTRL_FRC_MASK (0x03 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_16 (0 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_4 (1 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_FRC_2 (2 << LCD_CTRL_FRC_BIT)
#define LCD_CTRL_PDD_BIT 16
#define LCD_CTRL_PDD_MASK (0xff << LCD_CTRL_PDD_BIT)
#define LCD_CTRL_EOFM (1 << 13)
#define LCD_CTRL_SOFM (1 << 12)
#define LCD_CTRL_OFUM (1 << 11)
#define LCD_CTRL_IFUM0 (1 << 10)
#define LCD_CTRL_IFUM1 (1 << 9)
#define LCD_CTRL_LDDM (1 << 8)
#define LCD_CTRL_QDM (1 << 7)
#define LCD_CTRL_BEDN (1 << 6)
#define LCD_CTRL_PEDN (1 << 5)
#define LCD_CTRL_DIS (1 << 4)
#define LCD_CTRL_ENA (1 << 3)
#define LCD_CTRL_BPP_BIT 0
#define LCD_CTRL_BPP_MASK (0x07 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_1 (0 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_2 (1 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_4 (2 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_8 (3 << LCD_CTRL_BPP_BIT)
#define LCD_CTRL_BPP_16 (4 << LCD_CTRL_BPP_BIT)
#define LCD_STATE_QD (1 << 7)
#define LCD_STATE_EOF (1 << 5)
#define LCD_STATE_SOF (1 << 4)
#define LCD_STATE_OFU (1 << 3)
#define LCD_STATE_IFU0 (1 << 2)
#define LCD_STATE_IFU1 (1 << 1)
#define LCD_STATE_LDD (1 << 0)
#define LCD_CMD_SOFINT (1 << 31)
#define LCD_CMD_EOFINT (1 << 30)
#define LCD_CMD_PAL (1 << 28)
#define LCD_CMD_LEN_BIT 0
#define LCD_CMD_LEN_MASK (0xffffff << LCD_CMD_LEN_BIT)
static void udelay (unsigned us):
for unsigned i = 0; i < us; ++i:
for unsigned k = 0; k < 100; ++k:
IE (2) &= ~SPEN
static void mdelay (unsigned ms):
udelay (1000 * ms)
static unsigned int get_pllout ():
unsigned plcr = CPM_PLCR1
if (plcr & CPM_PLCR1_PLL1EN)
unsigned nf, nr, no
unsigned od[4] = {1, 2, 2, 4}
nf = (plcr & CPM_PLCR1_PLL1FD_MASK) >> CPM_PLCR1_PLL1FD_BIT
nr = (plcr & CPM_PLCR1_PLL1RD_MASK) >> CPM_PLCR1_PLL1RD_BIT
no = od[((plcr & CPM_PLCR1_PLL1OD_MASK) >> CPM_PLCR1_PLL1OD_BIT)]
return (JZ_EXTAL) / ((nr+2) * no) * (nf+2)
else
return JZ_EXTAL
// level is in the range [0, 300]
static void set_backlight (unsigned level):
DUT = level
if level:
CTR = 0xbf
D (2) |= PWM_ENABLE
else:
CTR = 0x3f
D (2) &= ~PWM_ENABLE
// Write to a register. Value must be in range [0, 0xff].
static void write_reg (unsigned reg, unsigned value):
unsigned data = (reg << 0xa) | 0x200 | value
D (2) |= SPEN
D (2) = (D (2) & ~SPDA) | SPCK
D (2) &= ~SPEN
udelay(25)
for unsigned i = 0; i < 16; ++i:
D (2) &= ~SPCK
if data & 0x8000:
D (2) |= SPDA
else:
D (2) &= ~SPDA
udelay (25)
D (2) |= SPCK
udelay (25)
data <<= 1
D (2) |= SPEN
udelay(200)
static void lcd_enable ():
udelay (50)
D (2) &= ~LCD_RET
mdelay(150)
D (2) |= LCD_RET
mdelay(10)
// These values have been copied from the linux source.
// I have no idea what they do.
write_reg (0x00, 0x03)
write_reg (0x01, 0x40)
write_reg (0x02, 0x11)
write_reg (0x03, 0xcd)
write_reg (0x04, 0x32)
write_reg (0x05, 0x0e)
write_reg (0x07, 0x03)
write_reg (0x08, 0x08)
write_reg (0x09, 0x32)
write_reg (0x0A, 0x88)
write_reg (0x0B, 0xc6)
write_reg (0x0C, 0x20)
write_reg (0x0D, 0x20)
set_backlight (300)
static void lcd_disable ():
write_reg (0x00, 0x03)
set_backlight (0)
static void reset ():
// Use gpio pins as pwm.
AUR (2) = (AUR (2) & ~0x0fffffff) | 0x50000000
// Use gpio pins as lcd master.
ALR (1) = (ALR (1) & ~0x0000ffff) | 0x55550000
AUR (1) = 0x556a5555
// initialize things.
IE(2) &= ~(PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA)
DI(2) |= PWM_ENABLE | LCD_RET | SPEN | SPCK | SPDA
udelay (50)
D (2) &= ~LCD_RET
mdelay (150)
D (2) |= LCD_RET
mdelay (10)
lcd_enable ()
// For now, support only 16 bpp.
// Screen is 800x480 tft.
LCD_CTRL = LCD_CTRL_BPP_16 | LCD_CTRL_BST_16
LCD_VSYNC = 20
LCD_HSYNC = 80
LCD_DAV = (20 << 16) | 500
LCD_DAH = (80 << 16) | 880
LCD_VAT = (880 << 16) | 500
LCD_CFG = MODE_TFT_GEN | PCLK_N | VSYNC_N
// Stop lcd.
CPM_MSCR |= 1 << 7
unsigned pclk = 60 * (800 * 3 + 80) * 500
unsigned pllout = get_pllout ()
CPM_CFCR2 = pllout / pclk - 1
unsigned v = pllout / (pclk * 4) - 1
while v < 0xf && pllout / (v + 1) > 150000000:
++v
CPM_CFCR = (CPM_CFCR & ~CPM_CFCR_LFR_MASK) | (v << CPM_CFCR_LFR_BIT) | CPM_CFCR_UPE
// Start lcd.
CPM_MSCR &= ~(1 << 7)
mdelay (1)
static void map_io (unsigned physical, unsigned address):
Capability page = memory_create_page (__my_memory)
alloc_physical (page, physical, 0)
memory_map (__my_memory, page, address, 1)
//drop (page)
int main ():
map_io (0x10010000, gpio_address)
map_io (0x10050000, pwm_address)
map_io (0x13050000, lcd_address)
map_io (0x10000000, cpm_address)
reset ()
while true:
Message msg
if !wait (&msg):
continue
switch msg.protected_data:
case LCD_BACKLIGHT:
set_backlight (c.data[0] > 300 ? 300 : c.data[0])
break
case LCD_RESET:
reset ()
break

View File

@ -1,23 +0,0 @@
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// thread1.ccp: Testing userspace thread.
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "iris.h"
int main ():
while true:
schedule ()

View File

@ -30,7 +30,6 @@ Capability *Memory::find_capability (unsigned code, bool *copy):
if p->data.frame == (unsigned)page:
return &page[num]
else:
code &= ~3
// Normal capability
for Capability *c = capabilities; c; c = c->next:
if c == (Capability *)code:
@ -47,37 +46,36 @@ bool Receiver::try_deliver ():
break
if !m:
return false
Capability::Context c
Capability *c[4]
for unsigned i = 0; i < 4; ++i:
c.data[i] = m->data[i]
if !m->capabilities[i]:
c.cap[i] = NULL
c[i] = NULL
else:
c.cap[i] = owner->address_space->clone_capability (m->capabilities[i], true)
if !c.cap[i]:
c[i] = owner->address_space->clone_capability (m->capabilities[i], true)
if !c[i]:
for unsigned j = 0; j < i; ++j:
owner->address_space->free_capability (c.cap[i])
owner->address_space->free_capability (c[i])
return false
Thread_arch_receive (owner, &c)
Thread_arch_receive (owner, m->data, c)
owner->unwait ()
return true
bool Receiver::send_message (unsigned protected_data, Capability::Context *c):
bool Receiver::send_message (unsigned protected_data, unsigned data[4], Capability *cap[4], bool copy[4]):
bool tried_direct = false
if owner && owner->is_waiting () && (protected_data == reply_protected_data || !protected_only):
Capability::Context n
Capability *c[4]
for unsigned i = 0; i < 4; ++i:
if !c->cap[i]:
n.cap[i] = NULL
if !cap[i]:
c[i] = NULL
else:
n.cap[i] = owner->address_space->clone_capability (c->cap[i], c->copy[i])
if !n.cap[i]:
c[i] = owner->address_space->clone_capability (cap[i], copy[i])
if !c[i]:
for unsigned j = 0; j < i; ++j:
owner->address_space->free_capability (n.cap[i])
owner->address_space->free_capability (c[i])
tried_direct = true
break
if !tried_direct:
Thread_arch_receive (owner, &n)
Thread_arch_receive (owner, data, c)
owner->unwait ()
return true
// The owner was not waiting, or it was not possible to deliver the message. Put it in the queue.
@ -85,11 +83,11 @@ bool Receiver::send_message (unsigned protected_data, Capability::Context *c):
if !msg:
return false
for unsigned i = 0; i < 4; ++i:
msg->data[i] = c->data[i]
if !c->cap[i]:
msg->data[i] = data[i]
if !cap[i]:
msg->capabilities[i] = NULL
else:
msg->capabilities[i] = address_space->clone_capability (c->cap[i], c->copy[i])
msg->capabilities[i] = address_space->clone_capability (cap[i], copy[i])
if !msg->capabilities[i]:
for unsigned j = 0; j < i; ++j:
address_space->free_capability (msg->capabilities[j])
@ -109,6 +107,8 @@ static void fill_cap (Capability *r, unsigned target, unsigned protected_data):
ref = &((Receiver *)target)->capabilities
else:
ref = &((Object_base *)protected_data)->refs
// alloc_capability needs a Memory, but it isn't used if return storage is given.
ref = &((Object_base *)protected_data)->refs
// alloc_capability needs a Memory, but it isn't used if return storage is given.
top_memory.alloc_capability ((Receiver *)target, NULL, ref, protected_data, r)
@ -628,91 +628,52 @@ static void page_invoke (unsigned target, unsigned protected_data, Capability::C
if !p:
new_flags &= ~PAGE_FLAG_FRAME
// If we can get the new frame, get it.
if new_flags & PAGE_FLAG_FRAME:
share_data->frame = raw_zalloc ()
// If the frame is lost, the page is no longer shared.
if old & ~new_flags & PAGE_FLAG_FRAME:
new_flags &= ~PAGE_FLAG_SHARED
if page:
if share_data->share_prev:
((Page *)share_data->share_prev)->data.share_next = share_data->share_next
if share_data->share_next:
((Page *)share_data->share_next)->data.share_prev = share_data->share_prev
else:
if share_data->share_prev:
((Cappage *)share_data->share_prev)->data.share_next = share_data->share_next
if share_data->share_next:
((Cappage *)share_data->share_next)->data.share_prev = share_data->share_prev
share_data->share_prev = NULL
share_data->share_next = NULL
// Set the shared flag.
if share_data->share_prev || share_data->share_next:
new_flags |= PAGE_FLAG_SHARED
// Don't allow making shared pages writable.
if ~old & PAGE_FLAG_WRITABLE:
new_flags &= ~PAGE_FLAG_WRITABLE
else:
new_flags &= ~PAGE_FLAG_SHARED
// Actually set the new flags.
share_data->flags = new_flags
// Update mappings if there is a change in writability, or in frame.
if page && ((share_data->flags ^ old) & PAGE_FLAG_WRITABLE || (share_data->flags ^ old) & PAGE_FLAG_FRAME):
Page_arch_update_mapping (page)
reply_num (share_data->flags)
break
case CAP_CAPPAGE_SET:
if !cappage || c->data[1] >= CAPPAGE_SIZE || !(target & CAP_PAGE_WRITE):
return
Capability *cap = &((Capability *)cappage->data.frame)[c->data[1]]
if cap:
cap->invalidate ()
// clone_capability needs a Memory, but doesn't use it when storage is provided.
top_memory.clone_capability (c->cap[0], c->copy[0], cap)
Capability *c = &((Capability *)cappage->data.frame)[data[1]]
c->invalidate ()
// clone_capability needs a Memory, but doesn't use it when storage is provided.
top_memory.clone_capability (cap, copy, c)
break
default:
break
static void capability_invoke (unsigned target, unsigned protected_data, Capability::Context *c):
static void capability_invoke (unsigned target, unsigned protected_data, Capability *cap, unsigned request, unsigned data):
Capability *capability = (Capability *)protected_data
switch c->data[0]:
switch request:
case CAP_CAPABILITY_GET:
reply_cap (capability, true)
break
default:
break
static bool kernel_invoke (unsigned target, unsigned protected_data, Capability::Context *c, Capability *self):
static bool kernel_invoke (unsigned target, unsigned protected_data, unsigned d[4], Capability *c[4], bool copy[4], Capability *self):
// Kernel calling convention:
// data[0] is the request.
// cap[0] is the reply capability
// other parameters' meanings depend on the operation.
if !((1 << d[0]) & target & ~REQUEST_MASK):
// You are not allowed to perform this operation.
return true
if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_CALL))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_CALL)):
// This is a call capability.
reply_receiver = (Receiver *)protected_data
reply_receiver->protected_only = !(target & (1 << CAP_RECEIVER_CALL_ASYNC))
Capability r
Capability *c0 = c->cap[0]
if (unsigned)c0->target & ~KERNEL_MASK:
// The call is not to a kernel capability.
Capability *c0 = c[0]
if ~(unsigned)c0->target & ~KERNEL_MASK:
fill_cap (&r, protected_data, reply_receiver->reply_protected_data)
c->cap[0] = &r
c->copy[0] = true
bool ret = c0->target->send_message (c0->protected_data, c)
c[0] = &r
copy[0] = true
bool ret = kernel_invoke ((unsigned)c0->target, c0->protected_data, d, c, copy, c0)
r.invalidate ()
return ret
else:
// Kernel call: don't create actual capablities.
reply = NULL
kernel_invoke ((unsigned)c0->target, c0->protected_data, c, c0)
return true
return kernel_invoke ((unsigned)c0->target, c0->protected_data, d, c, copy, c0)
if (target & (CAPTYPE_MASK | (1 << CAP_RECEIVER_REPLY))) == (CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_REPLY)):
// This is a reply capability.
Receiver *r = (Receiver *)protected_data
r->send_message (r->reply_protected_data, c)
r->send_message (r->reply_protected_data, d, c, copy)
while self->parent:
self = self->parent
while self->sibling_prev:
@ -721,42 +682,36 @@ static bool kernel_invoke (unsigned target, unsigned protected_data, Capability:
self->sibling_next->invalidate ()
self->invalidate ()
return true
// It's a normal kernel capability; check permission.
if !((1 << c->data[0]) & target & REQUEST_MASK):
// You are not allowed to perform this operation.
dbg_send (c->data[0], 5)
schedule ()
return true
if c->data[0] == CAP_DEGRADE:
reply_cap (target & (CAPTYPE_MASK | (c->data[1] & REQUEST_MASK)), protected_data)
reply = c[0]
if d[0] == CAP_DEGRADE:
reply_cap (target & d[1], protected_data)
return true
switch target & CAPTYPE_MASK:
case CAPTYPE_RECEIVER:
receiver_invoke (target, protected_data, c)
receiver_invoke (target, protected_data, c[1], d)
break
case CAPTYPE_MEMORY:
memory_invoke (target, protected_data, c)
memory_invoke (target, protected_data, c[1], d[0], d[1])
break
case CAPTYPE_THREAD:
thread_invoke (target, protected_data, c)
thread_invoke (target, protected_data, c[1], d)
break
case CAPTYPE_PAGE:
page_invoke (target, protected_data, c)
page_invoke (target, protected_data, c[1], copy[1], d)
break
case CAPTYPE_CAPABILITY:
capability_invoke (target, protected_data, c)
capability_invoke (target, protected_data, c[1], d[0], d[1])
break
case CAPTYPE_CAPPAGE:
page_invoke (target, protected_data, c[1], copy[1], d)
break
default:
panic (0x99337744, "invalid capability type invoked")
return true
bool Capability::invoke (Context *c):
bool Capability::invoke (unsigned data[4], Capability *cap[4], bool copy[4]):
if (unsigned)target & ~KERNEL_MASK:
// This is not a kernel capability: send a message to the receiver.
return target->send_message (protected_data, c)
return target->send_message (protected_data, data, cap, copy)
// This is a kernel capability. Use a function to allow optimized call capabilities.
reply = c->cap[0]
reply_receiver = NULL
return kernel_invoke ((unsigned)target, protected_data, c, this)
return kernel_invoke ((unsigned)target, protected_data, data, cap, copy, this)

49
iris.h
View File

@ -138,6 +138,7 @@ typedef struct Message
{
unsigned data[4];
Capability cap[4];
unsigned protected_data; /* only used for receiving. */
} Message;
static int invoke (Capability target, Message *msg)
@ -161,22 +162,26 @@ static int invoke (Capability target, Message *msg)
return ret;
}
static void wait (Message *msg)
static int wait (Message *msg)
{
int ret;
__asm__ volatile ("li $v0, 2\n"
"\tsyscall\n"
"\tlw $v1, %0\n"
"\tsw $t0, 0($v1)\n"
"\tsw $t1, 4($v1)\n"
"\tsw $t2, 8($v1)\n"
"\tsw $t3, 12($v1)\n"
"\tsw $a0, 16($v1)\n"
"\tsw $a1, 20($v1)\n"
"\tsw $a2, 24($v1)\n"
"\tsw $a3, 28($v1)"
:
"\tsw $v0, %0\n"
"\tlw $v0, %1\n"
"\tsw $t0, 0($v0)\n"
"\tsw $t1, 4($v0)\n"
"\tsw $t2, 8($v0)\n"
"\tsw $t3, 12($v0)\n"
"\tsw $a0, 16($v0)\n"
"\tsw $a1, 20($v0)\n"
"\tsw $a2, 24($v0)\n"
"\tsw $a3, 28($v0)\n"
"\tsw $v1, 32($v0)"
: "=m"(ret)
: "m"(msg)
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
return ret
}
static int call (Capability target, Message *msg)
@ -194,16 +199,18 @@ static int call (Capability target, Message *msg)
"\tlw $a2, 24($v1)\n"
"\tlw $a3, 28($v1)\n"
"\tsyscall\n"
"\tmove %0, $v0\n"
"\tsw $t0, 0($v1)\n"
"\tsw $t1, 4($v1)\n"
"\tsw $t2, 8($v1)\n"
"\tsw $t3, 12($v1)\n"
"\tsw $a0, 16($v1)\n"
"\tsw $a1, 20($v1)\n"
"\tsw $a2, 24($v1)\n"
"\tsw $a3, 28($v1)"
: "=r"(ret)
"\tsw $v0, %0\n"
"\tlw $v0, %2\n"
"\tsw $t0, 0($v0)\n"
"\tsw $t1, 4($v0)\n"
"\tsw $t2, 8($v0)\n"
"\tsw $t3, 12($v0)\n"
"\tsw $a0, 16($v0)\n"
"\tsw $a1, 20($v0)\n"
"\tsw $a2, 24($v0)\n"
"\tsw $a3, 28($v0)\n"
"\tsw $v1, 32($v0)"
: "=m"(ret)
: "m"(t), "m"(msg)
: "memory", "v0", "v1", "t0", "t1", "t2", "t3", "a0", "a1", "a2", "a3");
}

View File

@ -28,7 +28,7 @@ arch_kernel_sources = mips/interrupts.cc mips/test.cc mips/arch.cc
boot_sources = mips/init.cc
BUILT_SOURCES = $(kernel_sources) $(boot_sources)
arch_headers = mips/arch.hh
boot_threads = thread0 thread1
boot_threads = keyboard lcd
uimage:

View File

@ -54,6 +54,7 @@ void Thread_arch_receive (Thread *thread, Capability::Context *c):
thread->arch.t1 = c->data[1]
thread->arch.t2 = c->data[2]
thread->arch.t3 = c->data[3]
thread->arch.v1 = c->protected_data
thread->arch.v0 = 1
void Thread_arch_receive_fail (Thread *thread):